小型クロマトーン(Jankó鍵盤)作ってみた

前置き

最近音楽欲(?)が少し高まっているので、余暇に面白そうな記譜法が無いかググッていたところ、Clairnote(クレアノートかな?)なる記譜法を見つけてしまった。半音階を基にした記譜法であるが、直感的な調号によって調性を示すことができる点が優れている。

そこで(?)、同型鍵盤(Isomorphic Keyboard; 訳は 流行れ!同型鍵盤 (Isomorphic Keyboard) - めでたい - g.o.a.t に従った)を作ってみることにした。

f:id:na4zagin3:20210627003954j:plain

配列

同型鍵盤には様々な種類が考案されているが、ここでは、Toms Jansen により公開されている Arturia Keystep Janko Keys by TomsJensen - Thingiverse を用いることにした。これは、Arturia Keystep の鍵を換装し、六角形鍵のヤンコー配列 (Jankó layout)にするものである。

3Dプリンターは持ち合わせていないので、DMM.makeの3Dプリントサービスを用いることとした。

下準備

各鍵やキートップが別々のstlファイルになっているため、これをアップロードして其々必要数分発注しようとしたとこと、合計が凄い金額になったので、部品を必要数だけ含むstlファイルを作ることにした。

キートップ1つ分のstlファイルを40個分出力してもらうより、キートップ40個分のstlファイルを1つ出力してもらう方がぐっと安くなるのは納得が行かなかったのだけど、割り付けを手動でやっているとしたら、出力に係わる手間が減るのかもしれない)

stlファイルを結合するためにはOpenSCADを用いた。Python風の文法でプログラマティックに物体を設計することができるため、この種の用途には適していると思う。

f:id:na4zagin3:20210627134437p:plainf:id:na4zagin3:20210627134552p:plain
OpenSCADによる一括配置

scadファイルはGistで公開している。

gist.github.com

発注

今回は DMM.make に出力依頼をすることとしているので、前節で作成した Keys.stlKeyCapsWhite.stlKeyCapsBlack.stl を DMM.make にアップロードし、発注する。以下の素材を指定した。

ファイル 素材
Keys.stl PA12 ナチュラル(MJF)
KeyCapsWhite.stl アクリル(ソリッドカラー)Vero Pure White 研磨あり
KeyCapsBlack.stl アクリル(ソリッドカラー)Vero Black Plus 研磨あり

6月17日に発注し、6月25日に出荷された。

組み立て

基本的には、Arturia Keystep をバラし、鍵を換装するだけである。

注意点:

  • 表面がザラザラしているため、摺動面(他の部品と擦れるところ)はヤスリ掛けした方が良いかも?
  • 少なくとも摺動面にグリスは塗るべし。
  • 白鍵と黒鍵でバネが異なるので、組付ける時に間違えないように(バネが着色されているので間違えにくいとは思う)。
  • 出力された鍵は取り間違えやすいので、事前に整理して並べておくとよいかもしれない。
  • キートップを研磨してしまうとブカブカになって外れやすくなるので、接着剤でくっ付けた方がよいかもしれない。

f:id:na4zagin3:20210626145027j:plain
出力された鍵はこんなかんじ

f:id:na4zagin3:20210626145336j:plainf:id:na4zagin3:20210626150440j:plainf:id:na4zagin3:20210626204217j:plain
表面がザラザラしているので、摺動面(側面の内側)にヤスリを掛ける

f:id:na4zagin3:20210626210056j:plain
これを32回繰り返す……

f:id:na4zagin3:20210627142018j:plainf:id:na4zagin3:20210626230850j:plainf:id:na4zagin3:20210626233721j:plain
鍵を換装

f:id:na4zagin3:20210627000251j:plain
組み付け

f:id:na4zagin3:20210627003954j:plain
キートップを嵌めて完成

掛かった費用

費用は以下の通り。思ってたより高かった……。

Arturia Keystep 10,541円
3D出力:Keys.stl PA12 ナチュラル(MJF) 1個 40,277円
3D出力:KeyCapsWhite.stl アクリル(ソリッドカラー)Vero Pure White 1個 35,366円
3D出力:KeyCapsBlack.stl アクリル(ソリッドカラー)Vero Black Plus 1個 25,592円
合計 111,776円

ヤフオクでクロマトーンが時々1万円〜3万円で出品されているので、こちらを買った方がよかったのかもしれないが、3D印刷技術の学習費用と思えば……🥺

OfflineIMAP と Gmail

ふと GmailEmacs (Spacemacs) で 読みたくなったのと mu4e が気になってきたので、準備している。

mu4e はmu のフロントエンドであり、mu そのものには IMAP を使う術を持ち合わせていないために、OfflineIMAP を以って手許の Maildir と同期させる必要がある。

期待を裏切らず Archlinux WikiOfflineIMAP 項 が参考になる。また、本家マニュアル Gmail configuration (Mu4e 1.2.0 user manual)A Complete Guide to Email in Emacs using Mu and Mu4e も参考にした。

Google 側の設定

Google アカウント設定 でメール専用パスワードを発行する。詳しくは Sign in using App Passwords - Google Account Help を見よ。

その後、GMail の設定項目欄にて IMAP を有効化する。

OfflineIMAP の設定

# ~/.offlineimaprc
[general]
accounts = Gmail
maxsyncaccounts = 2
pythonfile = ~/.offlineimaprc.py

[Account Gmail]
localrepository = LocalGmail
remoterepository = RepositoryGmail
autorefresh = 5
quick = 10
postsynchook = mu index --maildir ~/Maildir

[Repository LocalGmail]
type = Maildir
localfolders = ~/Maildir/Gmail

[Repository RepositoryGmail]
type = Gmail
maxconnections = 2
remoteuser = <account>@gmail.com
remotepass = <password>

# folderfilter = lambda foldername: foldername not in ['[Gmail]/All Mail', '[Gmail]/Important']
sslcacertfile = /usr/local/etc/openssl/cert.pem

メールの件数にもよるが、信じられない程の時間が掛かる(体感0.7秒毎通)ので、もしかすると、[Gmail]/All Mail'[Gmail]/Important は同期対象から外した方が良いのかもしれない。

パスワードを Mac OS X のキーチェーンに格納したい場合には Use Mac OS X's Keychain for Password Retrieval in OfflineIMAP が参考になる。

また、IMAP4 ではメールボックス名は修正 UTF-7 でエンコードされていて、これは mu 等のメールクライアントの期待する形式ではない為に、非 ASCII 文字を含む mailbox 名を使いたければ、これを変換する必要がある。Utf 8 issues · sup-heliotrope/sup Wiki · GitHub を見よ。

mu4e の設定

Gmail configuration (Mu4e 1.2.0 user manual) を見よ。

(setq mu4e-maildir "~/Maildir/Gmail"
      mu4e-drafts-folder "/[Gmail].Drafts"
      mu4e-sent-folder   "/[Gmail].Sent Mail"
      mu4e-trash-folder  "/[Gmail].Trash")

;; don't save message to Sent Messages, Gmail/IMAP takes care of this
(setq mu4e-sent-messages-behavior 'delete)

;; (See the documentation for `mu4e-sent-messages-behavior' if you have
;; additional non-Gmail addresses and want assign them different
;; behavior.)

(setq
 user-mail-address "<username>@gmail.com"
 user-full-name  "<name>"
 mu4e-compose-signature
 (concat
  "<name>\n"))

(setq message-send-mail-function 'smtpmail-send-it
      smtpmail-stream-type 'starttls
      smtpmail-default-smtp-server "smtp.gmail.com"
      smtpmail-smtp-server "smtp.gmail.com"
      smtpmail-smtp-service 587)

グルジア行第二部(4日目〜7日目)

グルジア行記事第二部

四日目(クタイシ)

四日目は WST 社 のクタイシ行団体ツアーに参加した。

インド人・ロシア人・中国人(?)・サウジアラビア人等計約17人が参加し、案内は英語とロシア語で行われた。

f:id:na4zagin3:20190922105922j:plain
山道を往く

トビリシ—クタイシ間は高速道路 ს1 が通っているのだが、高規格なのはトビリシ—ハシュリ間までで、それ以後は対向二車線の一般道路である。グルジア国内道路網については https://upload.wikimedia.org/wikipedia/commons/8/89/E_Road_in_GEO.svg を見よ。

f:id:na4zagin3:20190922162219j:plain
クタイシ市内の大きな交差点

気がついたのだが、グルジアには殆ど信号が無い。都市部には点在するのだが、地方には皆無。代わりに円形交差点がそこかしこにある。

ゲラティ修道院を訪ねた。

f:id:na4zagin3:20190922165245j:plain
ゲラティ修道院

f:id:na4zagin3:20190922170344j:plain
ゲラティ修道院からの眺め

f:id:na4zagin3:20190922170012j:plain
ゲラティ修道院内の扉。アゼルバイジャン侵攻の折、持ち帰ってきたらしい

短パンで来ていたツアー参加者の東アジア人男性は、教会に入る際に注意され、上着でもって脚を隠していた。「No shorts」は性を問わず適用されているようだ。

黒衣に身を包んだ聖職者が白いバンに乗る場面は、日本のスクーターに跨る僧侶を彷彿とさせた。

f:id:na4zagin3:20190922152449j:plain
仔牛のシチューとハチャプリ

昼食時に日本に留学していたサウジアラビア人がいることが発覚した。帰りのバスは日本語で会話した。

f:id:na4zagin3:20190922185522j:plain
平原

五日目(カヘティ)

f:id:na4zagin3:20190923124545j:plain
ボドベ修道院からみた景色

予約時の不安は的中し、客は全員ロシア人で、案内人はグルジア語とロシア語しか話せないツアーだった。

f:id:na4zagin3:20190923100813j:plain
道中の醸造所でワイン試飲

途中、醸造所に立ち寄り見学兼ワイン試飲をしたのだが、セミスイートのワインは、飲み慣れない私にも飲み易く、お気に入りとなった。アイスワインもあったのでついでに購入した。

f:id:na4zagin3:20190923113939j:plainf:id:na4zagin3:20190923114700j:plain
道中のパン屋。これで一ラリ

f:id:na4zagin3:20190923124457j:plain
ボドベ修道院

ともかく、ガイドはロシア語で解説を行うので、何を言っているのだかさっぱり分からなかった。時々グルジア語で会話を試み、こちらの言うことは通じはしたのだが、しかし、こちらの語彙が少ないために返答が理解できず話が続かなかった……。

f:id:na4zagin3:20190923193623j:plain
チュルチヘラ(果汁と小麦粉を混ぜたもので胡桃を覆った菓子)

六日目(トビリシ

朝食に緑茶の茶葉が用意されていて驚いたのだが、グルジアでは緑茶も飲むそうだ。

トビリシ国立大学一号館へ向かうつもりだったのだが、よく分からないし、とりあえずトビリシ国立大学駅に行けば良いのではないかと思って移動した(大きな間違いであることには後に気付く)。

とりあえず地下鉄に乗りトビリシ国立大学駅に降りたつと、なんと、そこには、トビリシ国立大学は無かった! この駅名は大学の存在に由来するものではなく、トビリシ国立大学通りがそこまで通っているからであると思われる。

仕方が無いので、トビリシ国立大学一号館へとバスで移動しようとしたのだが、グーグルマップに従うとバスは途中で道を外れてしまい、役に立たなかった。トビリシ交通局の経路案内ページは役にたつがスマホでのユーザビリティが良くない。(今気が付いたのだが、スマホアプリが用意されているので、こちらを使えば良かったようである)

f:id:na4zagin3:20190925142212j:plain
バス停

なんとか交通局の経路案内ページを使って正しいバスを探しだして乗った。石畳の急坂をバスがウンウン唸りながら登っていき、ようやく辿り着いた時には疲労困憊状態であった。

f:id:na4zagin3:20190924144710j:plain
トビリシ国立大学一号館(3mはある正扉は今だに使われている)

大学書店に入った所、値段が安すぎて貸出用の金額なのではないかと不安になり、学生と思しき人を捕まえて「本当に買えるのか?」と尋ねようとするも、英語が分からないようで撃沈……。グルジア語に切替えようにも、表現がなかなか出てこない。仕方が無いのでグーグル翻訳を併用しなんとか聞き出すことに成功し、やはり売値であることが確かめられたので、大量に買い込んだ。

帰路、お好み焼き屋台を見つけた。

f:id:na4zagin3:20190924163431j:plainf:id:na4zagin3:20190924163453j:plain
ピッコロカフェ横お好み焼き屋台
goo.gl

f:id:na4zagin3:20190924180942j:plain
ブドウのレモネード

7日目朝(トビリシ

本の博物館に行った。

f:id:na4zagin3:20190926113559j:plainf:id:na4zagin3:20190926113615j:plain
最古のグルジア語印刷物(辞書・文法書)

f:id:na4zagin3:20190926115039j:plain
ベラルーシからの寄贈品だそうである

写本博物館にも行った

f:id:na4zagin3:20190926124242j:plain
本当に入って良いのか不安になる入口

f:id:na4zagin3:20190926130029j:plain
ヌスフリ体による写本……格好良い!

f:id:na4zagin3:20190926130359j:plain
天文学の本
古代ギリシャ語に馴染みがある人ならすぐに六十進数表記による数表と理解し、200までの表記を拾うことができたことであろう。

f:id:na4zagin3:20190926132852j:plain
ショタ・ルスタヴェリ『虎皮の騎士』

7日目午後〜(移動)

ホテルの人にタクシーを呼んでもらった。フロントの人には「50ラリだけど良い?」と確認されたので、てっきり価格は規定なのかと思っていた所、運転手(アゼルバイジャン人)に「いくら払う?」と訊かれ意味が分からず、日本・グルジア間の旅費の問題と思って謎問答をしたりしてしまった。最終的に「ホテルの人には50ラリだと言われた」と返したら鼻で笑われて、100ラリを吹っ掛けられ、最終的には更にガソリン代として3ラリ余計に請求された(が、混乱していたのでガソリン代分は払わなかった。払った方が良かったのだろうか?)。

f:id:na4zagin3:20190926184216j:plain
トビリシ空港内免税店

f:id:na4zagin3:20190926184855j:plain
グルジア語が読めない人には肝腎な内容を伝えない看板

復路は往路の反対で、トビリシ→ドーハ→羽田である。

トビリシ→ドーハ間の航空機で真後に座っていたオッサンはともかく大声で周囲と話し、また、頻繁に自席・床・前席(即ち私の席)を叩きまくるため、振動で不快だった。稀に二分間程停止してくれるが、ああいう人は飛行機に向いていないのではなかろうか(尚、数年前にアメリカ国内線で泣き喚き暴れまくる幼児の前で笑顔を絶やさず耐えざるを得なかったのが思い起こされた)。

ドーハ空港には仮眠室があり、ここで朝まで休むこととした。若干風があるので、毛布か何かを持ち込むことを奨める。

日本行の飛行機の搭乗ゲートの開く時間となり、長椅子に座り搭乗を待っていると、6時間前に見た集団が隣に……! 訊けばラグビー観戦に来るのだとか。

ドーハ→羽田間の航空機では好運なことに煩いオッサンとは離れた席で静かに過ごすことができた。

グルジア行第一部(1日目〜3日目)

九月末に約一週間グルジアジョージア、又サカルトヴェロ)へ一人旅をしてきたので、その記録。

事前準備

以下の事をした

  • 航空券予約(往路:羽田→ドーハ→トビリシ及び復路)
  • パスポート紛失再発行に要する書類の準備(戸籍抄本発行、顔写真撮影)
  • 海外保険契約(AIU
    • ジョージアはどこの地域に含まれるか不明で、適当に「ヨーロッパ」を選択した。申込後に電話問い合わせをして判明したのだが、「その他」を選ぶのが正解であったそうである。
  • イモトのWiFi で契約
    • 容量は400MB毎3日だったのだが、そもそも回線速度が遅かったために上限に達しなかったような気がする。
  • private 一日個人ツアーの申込
    • group tour 周りの仕組みを全く知らなかったので、不安だったのだが、真相は以下の様である。
      • private tour であるものと、そうでないものの二種がある。private tour は、申込した一団体のみをガイド・運転手が案内する形式であり、一人だけで申込できるツアーは少ない。private tour でないものは、申込した団体全てを一緒にして旅行を行う形式である。

一日目(移動)

飛行機移動

つい前日まで出発空港を成田と勘違いしており、事前確認をしていなければ危なかった。

現地で日本円からラリに両替するのは困難だったりレートが悪かったりすると聞いたので、古本を購うことを考え必要額を米ドルに両替した。現地で下ろすことが出来ることは知っていたものの、万が一引き出し手段を失った時の事を考え現金を用意した。

カタール航空に乗ったのは初めてだったのだが、紫のシートが気品ある感じだったし、配布の毛布が厚手だったのが好印象。ナイフやフォークが金属製なのに驚いた。背の低い容器に水なりジュースなりが入ったものが食事の際に出てきたのだが、アラブ圏の慣習なんだろうか。

f:id:na4zagin3:20190919112835j:plain
ドーハ空港の謎の像

ドーハ→トビリシの飛行機にて他の日本人を見掛けたのだが、話しかけられなかった。 また、インド人が多かった。

空港からホテルまではトビリシ交通局バス(乗車賃0.50ラリ、つまり約20円)を使うつもりだったのだが、スーツケースが大きかったこととタクシー運転手が強引だったことでタクシーに乗ってしまった。空港から旧市街まで70ラリだった。

現地ホテル

ホテルに WiFi はあるものの、しかし、3階の我が部屋まで届かない。同階の女性が部屋から出て階段中ばで変なポーズを取っているのを見かけたのであるが、通信しようと頑張っていたのだろう。

AU 世界データ定額

せっかく用意されているのだし、AU の世界データ定額を利用しようと試すも繋がらず、連絡を試みる。SamsungGalaxy S8 は電話回線すら繋がらず、サブ機のiPhone 8で掛けたところ繋がった。遅延が数秒あって面白かった。

  • WiFi を無効化→効かず
  • リセット→効かず
  • Chrome の履歴を削除(私はそんなもの効く訳が無いと思ったのだが、渋々消すことに。削除に時間が掛かっていると伝えると「ほら、いっぱいあるから」とあたかも履歴に問題があるかのような返事が……。無論効果は無かった)
  • 現地事業者はsilknet(GEO)が優先的に選択されるようなのだが、これを MAGTI に手動変更。これが効いた。

AU では Silknet と Magti の両者との契約を結んでいるそうであるが、Silknet 側の設定に問題があって使用できないのだろう。

二日目(ムツヘタ・トビリシ

個人ツアーだったのだが、とりあえず、初手グルジア語で自己紹介して意気投合する。

ムツヘタに向かう。

十字架僧院(ムツヘタ)

f:id:na4zagin3:20190920102323j:plain
十字架僧院(ჯვრის მონასტერი /d͡ʒvris monastʼeri/)

ムツヘタ近くの丘の上に建っている僧院である。

日本ならそこかしこに柵が設置されそうな場所ではあるが、そのようなものは無い。

時々角笛の音が外から聞こえた。歌声も聞こえる。礼拝か何かなんだろうとこの時は思っていた。

内に居る時に聖職者が苛立たしそうに外を見ようと立ったり座ったりしているので、案内人に聞いた所、「外でうるさくする人がいるので聖職者が怒っている」とのことであった。

スヴェティツホヴェリ大聖堂(ムツヘタ)

f:id:na4zagin3:20190920102655j:plain
ムツヘタ市街。中央に見えるのがスヴェティツホヴェリ大聖堂(სვეტიცხოვლის საკათედრო ტაძარი /svetʼit͡sxovlis sakʼatʰedro tʼad͡zari/)

f:id:na4zagin3:20190920114818j:plain
スヴェティツホヴェリ大聖堂内アルゴナウティカの場面を描いた壁画

f:id:na4zagin3:20191007224847j:plain
墓石(グルジア語・アラビア語

f:id:na4zagin3:20191008010211j:plain
教会裏の碑文

教会裏にムヘドルリで書かれた文があったのだが、ガイドの人は「文字は分かるんだけど、全く意味が分からない」とのことであった。

f:id:na4zagin3:20190920120801j:plain
葡萄十字(ჯვარი ვაზისა /d͡ʒvari vazisa/)

教会から出るとまた角笛の音と音楽が聞こえてきた。見ると、東アジア風の相貌の老男女(夫婦か?)が近付いて来ており、男は五星紅旗を配したパステルカラーのリュックサックを背負いながら角笛を吹き鳴らし、女は持ち抱えているスピーカーから大音量でヘンデルのオラトリオ「メサイア」を流しながら「ハレルヤ!!」と叫び、おもむろに教会入口へと歩を進めているではないか。この尋常ならざる事態に黒山の人集りが出来、また、聖職者が進入を拒否せんと入口前で立ちはだかり誰何するものの、夫婦は声調言語(中国語だろうか)で怒鳴ったり、胸を叩いて「ハレルヤ」と声を張り上げるだけで、両者に会話は成立していないようだった。最終的に、夫婦は断念して恨めしそうに場を去ることと相成った。隣の見物人から「あれ誰? 何をしているの?」と訊かれたのだが、「中国人であるようには見える(中国人以外が五星紅旗を身に付けるだろうか?)のだが、何を言っているのかも何をしているのかも分からない……」と答えるしかなかった。

f:id:na4zagin3:20190920123509j:plain
栃ノ進の看板

ムツヘタ市街に至る道中に栃ノ進の看板があったのだが、今思えば設置目的は何だったのだろうか。

ナリカラ砦(トビリシ

トビリシ市街に戻りナリカラ砦(ნარიყალას ციხესიმაგრე /nariqʼalas t͡sixesimagre/)に登る。

f:id:na4zagin3:20190920155911j:plain
ナリカラ砦のある丘からの展望

なお、ここからトビリシ植物園併設の日本(風)庭園を俯瞰することができる。突然視界に入ってくる鳥居の理由を調べるのに夢中で写真を撮り忘れてしまったのが残念である。ガイドの人も知らなかったそう。

www.tbilisi.gov.ge

三日目(トビリシ

朝、フロントにクリーニングを頼む。上下一着と下着二日分で30ラリ。

f:id:na4zagin3:20190922081319j:plain
トビリシには野犬が多い。昼は寝て、夜吠えだす。耳のタグはワクチン接種済の証

四日目と五日目の予定を決めるために街をぶらつく。 街中に両替商がおり、空港内の両替商と大して変わらない良レートで両替している所があったたりした。

f:id:na4zagin3:20190921115401j:plain
そこら中にEU旗がはためいている

街中では主に旅行会社、タクシー、レストランによる呼び込みが行われており、また、「貸し出し中 連絡先……」の表示がある車が大量に駐車されていた。

ある旅行会社の呼び込みに反応して、カヘティ行きのツアーを申し込んでみた。ロシア人女子によって呼び込みがされているので、もしかするとツアー参加者も案内人もロシア語話者で占められるのではないかと一抹の不安があった。

また、クタイシ行きのツアーは大きめの旅行会社に申し込んでみた。

f:id:na4zagin3:20190924170856j:plain
本の行商

旧市街ではロシア語による表記も多かった。また、物を並べられそうな空間には決って本の行商がいた。

グルジア語の本を探していたら研究者に話かけられた。曰く、「古グルジア語の本が欲しいなら、トビリシ国立大学一号館の大学書店に来なさい。ます現代語が出来ないといけないけどね」「現状、グルジア語を能く話す日本人は三人いる。東京都市大学の前田弘毅、学生だった五月女颯、そして今はトビリシにいる児島康宏だ。お前は四人目になりに来たのか?」と。アカデミア以外にはもう少しいると思うのだが、ともかくこの三人が有名であることは間違いなさそうだ。

f:id:na4zagin3:20190921151648j:plain
ヒンカリ

小籠包の皮を厚くして、内容量も増したようなものである。さしずめ大籠包か? 非常に美味しい。

第二部へ続く

髭文字の読み方

ヒトラーによって髭文字(ブラックレター)は廃止されてしまったものの、昔のドイツ語の本を読むときには知らないといけない。 ここでは、フラクトゥーア体の文字を特徴別に分類(重複あり)して紹介する。

大文字

ABCDEFGHIJKLMNOPQRSTUVWXYZ

IとJは区別されないこともあるし、区別されることもある。 ウムラウトは、上に点々を付して表されることもあれば、eを上に書くこともあるし、Ueのように書くこともある。

左下が半円

CEGS

  • C E G: 左から順に C E G。よく似ているので注意。
  • S: S であって、G G ではないことに注意。フラクトゥーアで面喰う文字第二位(個人的感想)。

左上から最左の竪画に入る

AMRNVBWY

  • A: A であって U U ではない。フラクトゥーアで面喰う文字第一位(個人的感想)。
  • R N Y: 左から R N Y。R R を K K と間違えないように。
  • M W: 左から M W。
  • B V: 左から B V。

N M N M と V W V W は最右の竪画が同じ形をしている。

R NB V は当時の人にとっても紛らわしかったようで、偶に誤植されている。

最左の竪画の上が右上に流れる

HKL

  • H: H。Y Y と紛らわしいこともあるかもしれないが、中央の横画の位置でも判別がつく。(H H は中腹から横画が引かれる。Y Y は上から。)
  • K: K。初心者は R R と間違えやすい。
  • L: L。これは分かりやすい。

上部に太い横画

DTFIJ

  • D T: 左から D T。
  • F: F。
  • I J: I と J の区別のある場合は、左から I J なのだが、そもそも区別されないことが多い。

右が垂直な竪画

AU

  • A U: 左から A U。A A の左の竪画は必ず、2 の字に曲っているが、U U の左の竪画は真っ直ぐなことが多い。

円形

PVDOQ

  • O Q: 左から順に O Q。
  • V D: 左から順に V D。
  • P P。古い本で冪集合記号として使われているのをよく見るかもしれない。P P の右側が V V の様になっているものもある。

XZ

  • X X。
  • Z Z。

分かりやすい。

小文字

abcdefghijklmnopqrsſtuvwxyzß

小文字は大文字とは違って馴染み深い形をしているものが殆どなので、そうでないもののみ、例を挙げて解説する。

  • f ſ s ß 左から f ſ s ß。ここで、ſ ſ はいわゆる長い s (s longa) であって、語頭・語中で用いられるものである。対して、s s は丸い s (s rotunda) と呼ばれ、語末(正確には複合語中の形態素末も含む)でしか用いられない。偶に f ſ が誤植されているように見えるものがある。
  • r x 左から r x。r r の字形に驚く向きは無かろうが、 x x は面喰うかもしれない。
  • l k 左から l k。低品質なスキャン画像だと、k k と l l に塵のついたものを区別しづらいことがある。
  • n y 左から n y。あまり y y は出てこないかもしれないが、気を抜いていると n n に見えてしまうことがあるので注意。
  • z z。合字(見次項)になるとクルクルが取れる。

合字

以下の二字の組み合わせが語中に存在した場合は必ず合字になる。

ch ck ß tz: ch ck ß tz

また、以下の組み合わせが語中に存在した場合も合字になる。

ll ff fl ſi ſſ fi ſt: ff fl ll ſſ ſt

しかし、beſitze/Zeit‌zoneのように、複合語中の語境界(Zeit-zone)を跨がって合字になることはない。これにより、複合語中の語境界を(一部の場合に)明示することが可能になり、この点においては、フラクトゥーアによる表記は現在のローマン体によるものよりも優れているものと私には思われる。

隔字体 Sperrsatz

フラクトゥーアにはイタリックが無かった。強調の為には字間空白を各文字の間に挿入することが行われた*1。この時、ch ck ß tz ch ck ß tz は分離しない。その他の合字は分離する。

以下のようになる。

  • glückliche: g l ü ck l i ch e
  • ſchon: ſ ch o n
  • ſtellen: ſ t e l l e n

フォント

オープンソースフォントならば UniFraktur がお勧めである。 UniFraktur • Free fraktur font reſources

また、試してみたことは無いが、Linotype も合字に対応したフラクトゥーアのフォントを多く扱っている。dlig と hlig に対応しているものは、フラクトゥーアに必要な合字に対応しているのではなかろうか。

*1:行末の語の後半が意味も無く隔字体になっていることがある。これは、行末を揃えるために語空白だけでは足りなかった場合に行われている様である。

古典ギリシャ語の仮名転写について

古典ギリシャ語の仮名転写には、いくらかの方法がある。以下の記事にも、「アッリアーノス(アリアーノス)(アリアノス)」のように複数の転写が書かれている。 toxa.cocolog-nifty.com

現代において広く行われている方式を、本稿では統一的に提示する。

尚、断りの無い限り、ギリシャ文字表記は現代に通行するものとする。また、発音欄に音韻変化が記されている場合は、最右が古典期のものである。

母音

以下の点で対立する。

  • 母音の長短を区別するか否か
    • ここでは、区別するものを有長母音式、区別せぬものを無長母音式とする
  • 下書きのイオタを表記するか否か
    • ここでは、区別するものを有ι式、区別せぬものを無ι式とする

短母音

短母音の転写は殆ど違いが無い。

表記 発音 仮名
ι /i/
ε /e/
α /a/
ο /o/
υ /u/ > /y/

例:

表記 発音 仮名
υἱός /hyiós/ ヒュイオス
ἄνεμος /ánemos/ アネモス

長母音

長母音には方式による差が存在しうる。有長母音式による転写表記を示す。無長母音式による転写は、長音符を取り去ることにより得られる。

偽の二重母音であっても、ει は「エイ」と転写する。

表記 発音 仮名
/iː/ イー
ει /eː/ エイ
η /ɛː/ エー
/aː/ アー
ω /ɔː/ オー
ου /oː/ > /uː/ ウー
/uː/ > /yː/ ユー

例:

表記 発音 仮名
ῑ̕ᾱτρός /iːaːtrós/ 有長母音式:イーアートロス、無長母音式:イアトロス
οὐσίᾱ /uːsíaː/ 有長母音式:ウーシアー、無長母音式:ウシア

二重母音

二重母音には方式による差が存在する。有長母音式による転写表記を示す。無長母音式による転写は、長音符を取り去ることにより得られる。

真の二重母音は、古典期には既に長母音化していたものと考えられているが、ει は「エイ」と転写する。

表記 発音 仮名
ει /ei̯/ > /eː/ エイ
αι /ai̯/ アイ
οι /oi̯/ オイ
υι /yi̯/ ユイ
/ɛːi̯/ 有ι)エーイ/(無ι)エー
/aːi̯/ 有ι)アーイ/(無ι)アー
/ɔːi̯/ 有ι)オーイ/(無ι)オー
ευ /eu̯/ エウ
αυ /au̯/ アウ
ου /ou̯/ > /uː/ ウー
ηυ /ɛːu̯/ エーウ
ᾱυ /aːu̯/ アーウ
ωυ /ɔːu̯/ オーウ
表記 発音 仮名
Αἴᾱς /aí̯aːs/ 有長母音式:アイアース、無長母音式:アイアス
Ἅιδης /haːí̯dɛːs/ 有長母音・有ι)ハーイデース、(有長母音・無ι)ハーデース、(無長母音・無ι)ハデス

子音

以下の点で対立する。

  • 有気無声音の表記
    • ここでは、無声閉鎖音として転写するものを有気音無声式、摩擦音として転写するものを有気音摩擦式とする。
  • 流音の長子音
    • ここでは、「ッ」を用いて短子音と区別するものを有長流音ッ式、区別せぬものを無長流音式とする。
  • 鼻音の長子音
    • ここでは、「ン」を用いて短子音と区別するものを有長鼻音ン式、「ム・ン」を用いて短子音と区別するものを有長鼻音ム式、区別せぬものを無長鼻音式とする。
  • μ + 唇音
    • ここでは、「ン」を用いるものを唇音ム式、「ム」を用いるを唇音ン式とする。

断りの無い限り、例示には有長母音式を用いる。

用いる仮名

仮名文字は音節文字であるので、子音(行)に後続する母音(段)も纏めて一塊として表示される。 子音が後続する場合は、適当な母音(多くの場合はウ、タ行とダ行のみオ)を補って表示される。 以下に音節表を示す。

古典ギリシャ語には短い /u/ が存在しないことから、有長母音式転写表記において、子音のみを表す仮名と子音と母音の対を表す仮名は、タ行とダ行を除き識別される。

ア段 イ段 ウ段 エ段 オ段 ユ段 無母音
ア行
カ行 キュ
ガ行 ギュ
サ行 シュ
ザ行 ジ? ジュ
タ行 ティ トゥ テュ
ダ行 ディ ドゥ デュ
ナ行 ニュ
ハ行 ヒュ ハ? フ?
ファ行 ファ フィ フ? フェ フォ フュ? フ?
パ行 ピュ
バ行 ビュ
マ行 ミュ
ラ行 リュ

仮名との対応

以下にギリシャ文字子音文字と仮名文字音節の対応を示す。

ρ と λ は、どの方式でも区別されない。 有気音 φ θ χ は、方式にもよるが、いずれにせよ他の子音と衝突する。

また、流音・鼻音(ρ, λ; μ, ν)の無声化は仮名転写には反映されない。

表記 発音 仮名
β /b/ バ行
δ /d/ ダ行
γ /ɡ/ ガ行
π /p/ パ行
τ /t/ タ行
κ /k/ カ行
φ /pʰ/ 有気音無声)パ行/(有気音摩擦)ファ行
θ /tʰ/ 有気音無声)タ行/(有気音摩擦)サ行
χ /kʰ/ 有気音無声)カ行/(有気音摩擦)ハ行??
μ /m/ マ行
ν /n/ ナ行
γ /ŋ/ ガ行
ρ /r/ ラ行
λ /l/ ラ行
σ /s/ サ行
ζ /sd/ [zd] ザ行
ψ /ps/ πσ として扱う
ξ /ks/ κσ として扱う
気息記号 /h/ ハ行
無気息記号 /∅/ ア行

母音に先行する場合

前節と前々節に従う。

表記 発音 仮名
ἀποκάλυψις /apokálypsis/ アポカリュプシス
Ζεύς /sdeú̯s/ ゼウス
Λητώ /lɛːtɔ̌ː/ レートー

子音に先行する場合

閉鎖音 β, δ, γ; π, τ, κ; φ, θ, χ

表記上、同一調音点の閉鎖音が後続する場合(ππ, ττ, κκ; πφ, τθ, κχ)、即ち発音において長子音になる場合[要引用]は「ッ」と表記される。その外の場合は「用いる仮名」表に従う。

表記上、異なる調音点の閉鎖音が後続する場合で、無声無気・無声有気・有声が一致していない場合がある。この場合、発音は逆行同化していたものと考えられているが、仮名転写は表記通り行う。

表記 発音 仮名
ἵππος /híppos/ ヒッポス
Σαπφώ /sappʰɔ̌ː/ 有気音無声)サッポー/(有気音摩擦)サッフォー
Βάκχος /bákkʰos/ 有気音無声)バッコス/(有気音摩擦)バッホス??
ὄγδοος /óɡdoos/ オグドオス
Τμῶλος /tmɔ̂ːlos/ トモーロス
Φθία /pʰtʰǐːaː/ 有気音無声)プティーアー/(有気音摩擦)フティーアー?
ἐκβάλλω /eɡbállɔː/ エクバッロー(エグバッローではない)

鼻音 μ

唇音 β π φ が後続する場合、(唇音ン式)「ン」と表記されるか(唇音ム式)、「ム」と表記される。 μ が後続する場合、(有長鼻音ン式)「ン」と表記されるか、(有長鼻音ム式)「ム」と表記されるか、(無長鼻音式)単に無視される。 その外の場合は「用いる仮名」表に従う。

表記 発音 仮名
Ὀλυμπία /olympíaː/ 唇音ン式)オリュンピアー、(唇音ム式)オリュムピアー
γάμμα /ɡámma/ 有長鼻音ン式)ガンマ、(有長鼻音ム式)ガムマ、(無長鼻音式)ガマ
μνημοσύνη /mnɛːmosýnɛː/ ムネーモシュネー

鼻音 ν, γ

表記上、同一調音点の子音が後続する場合は、「ン」と表記される。但し、発音上長子音となる場合(νν)は、(有長鼻音ン・ム式)「ン」と表記されるか、(無長鼻音式)単に無視される。その外の場合は「用いる仮名」表に従う。

表記 発音 仮名
Πελοπόννησος /pelopónnɛːsos/ 有長鼻音ン・ム)ペロポンネーソス、(無長鼻音)ペロポネーソス
ἄγγελος /áŋɡelos/ アンゲロス
Ἀντιγόνη /antiɡónɛː/ アンティゴネ
σίγμα /síŋma/ シグマ

流音 ρ, λ

表記上、同一の子音が後続する場合、即ち発音に長子音となる場合は、(有長流音式)「ッ」と表記されるか、若くは、(無長流音式)単に無視される。その外の場合は「用いる仮名」表に従う。

表記 発音 仮名
ἅλς /hals/ ハルス
ἄρθρον /ártʰron/ アルトロン
παράλληλος /parállɛːlos/ 有長流音)パラッレーロス/(無長流音)パラレーロス
Ἀρριδαῖος /arridái̯os/ 有長流音)アッリダイオス/(無長流音)アリダイオス

摩擦音 σ

表記上、同一の子音が後続する場合、即ち発音に長子音となる場合は、「ッ」と表記される。その外の場合は「用いる仮名」表に従う。

尚、σ /s/ が有声化し [z] と発音される場合でも、「ス」と表記される。

表記 発音 仮名
Ἁλικαρνᾱσσός /halikarnaːssós/ ハリカルナーッソス
σκορακισμός /skorakismós/ [skorakizmós] スコラキスモス

複子音 ζ, ψ, ξ; 気息記号

音韻変化等の理由により後続する子音は無い。

語末

例外を除き、語末には ν /n/ か ρ /r/ か ς /s/ しか許されない。それぞれ、「ン」と「ル」と「ス」と表記される。/n/ は後続の音に同化していたものと考えられているが、日本語の「ン」も同化に関しては同じであるので、総じて「ン」で転写する。

例外は、ἐκ, οὐκ であるが、こういう語を仮名表記することは考えづらいので、どうするのが正解なのかは私には分からない。以下の二つのうちのどちらかであろう。

  1. それぞれ、「エク」「ウーク」(無長母音式なら「ウク」)と転写する。
  2. 後倚辞であるので、後続の語に繋げる。
    1. ἐκ の末尾子音は後続の音に応じて変化していたものと考えられているので、これを反映した転写を行う。
    2. ἐκ の末尾子音の変化はこれを無視する。
表記 発音 仮名
τᾶν /tâːn/ ターン
φύσις /pʰýsis/ ピュシス

アクセント

アクセントは仮名転写にては無視される。

諸体系(随時更新)

情報求む。

体系 長母音 下書きのι 有気無声音 流音の長子音 鼻音の長子音 μ + 唇音
ウィキペディア ギリシャ神話*1 無ι 有気音無声 無長流音 無長鼻音
高津訳アポロドーシス『ギリシア神話岩波書店 無ι 有気音無声 無長流音 無長鼻音・稀に有長鼻音ム 唇音ム
根本訳クセノポン『ギリシア史』西洋古典叢書 無ι*2 有気音無声 無長流音*3 有長鼻音*4 ?
高津『ギリシア語文法』岩波書店 *5、無*6 無ι*7 有気音無声*8、有気音摩擦*9 無長流音*10 ? 唇音ム*11、唇音ン*12 *13
古川訳アンティポーン『ヘーローイデース殺し』大学書林 有ι 有気音無声 ? ? ?
古川訳『「オデュッセイア」より——嵐とパイーケス人の国』大学書林 ? 有気音無声 ? ? ? *14
田中・松平『ギリシア語入門』岩波書店 無ι*15 有気音無声 有長流音*16、無長流音*17 有長鼻音*18 唇音ン*19

更新履歴

2018-02-04 脚注等の修正 2018-02-04 公開

*1:プロジェクト:ギリシア神話 - Wikipedia

*2:Θρᾷξ トラク

*3:Ἑλλάς ヘラス

*4:Πελοπόννησος ペロポンネソス

*5:p. 60 ニーキアースの、p. 71 デーメーテール、p. 87 アテーナイ

*6:p. 87 アテナイ

*7:p. 87 ハーデース

*8:p. 127 アカイア人、p. 371 イストモス、ピリッポス

*9:p. 124 ファランクス、スフィンクス

*10:p. 370 ヘレースポントス

*11:p. 376 アムプラキア、p. 399 オリュムポス

*12:p. 84 オリュンピア祭

*13:p. 395 メセーニア(しかし、p. 317 テッサリア

*14:p. 35 ナウスィカアー

*15:p.298 Ὠιδεῖον オーデイオン

*16:p. 299 Ἀχιλλεύς アキッレウス、(p. 267 Ἀπόλλων アポㇽローン)

*17:p. 167 Ἀρριᾱνός アリアーノス

*18:p. 288 ペロポンネーソス

*19:p. 159 オリュンピア競技

Haskell で relational-record を使って MySQL に繋いでみた

HaskellSQL函数型的に構築する方法としては、relational-record(以下、HRR と称す)と opaleye があるようだ。 今回は relational-record を選択してみた。

以下の記事が参考になるが、本稿執筆時点(2017年12月28日)では、少々変更があったり、嵌ったことがあったので、差分を記述する。 qiita.com

インストール

Stack を前提とする。以上のコマンドで、hrr-test なる名のパッケージが作られる。

$ stack new hrr-test

新し目の Stack ではデフォルトで hpack を利用したテンプレートが使われる。HRR は Stackage に登録されているために、package.yaml の dependencies 節に HRR 関連のパッケージを追加するだけでよい。

dependencies:
- base >= 4.7 && < 5
# ここより下を追加
# HRR
- relational-record
- relational-query
- relational-query-HDBC
- persistable-record
# データベース
- HDBC
- HDBC-mysql
# その他必要なパッケージ
- template-haskell
- time
- bytestring

DataSource.hs

DataSource.hs は以下のようになるだろう。

{-# LANGUAGE TemplateHaskell, TypeSynonymInstances #-}
module DataSource

import Data.ByteString (ByteString)
import Data.Time.Clock.POSIX (POSIXTime, posixSecondsToUTCTime)
import Data.Time.LocalTime (TimeZone, utcToLocalTime, hoursToTimeZone)
import Database.HDBC.Query.TH (defineTableFromDB)
import Database.HDBC.MySQL (MySQLConnectInfo, Connection, connectMySQL, defaultMySQLConnectInfo, mysqlUser, mysqlPassword, mysqlDatabase, mysqlHost, mysqlPort)
import Database.HDBC.Schema.MySQL (driverMySQL)
import Database.HDBC.Schema.Driver (driverConfig, typeMap)
import Database.Relational.Config (normalizedTableName, defaultConfig)
import Database.Relational.ProjectableClass (ShowConstantTermsSQL(..), showConstantTermsSQL)
import Language.Haskell.TH (Q, Dec, TypeQ)

connect :: IO Connection
connect = connectMySQL defaultMySQLConnectInfo
    { mysqlHost = "<mysql-host>"
    , mysqlDatabase = "INFORMATION_SCHEMA"
    }

-- haskell-relational-record-0.1.4.0 には MEDIUMINT の定義はあるが、SET や ENUM はない。
typeMap :: [(String, TypeQ)]
typeMap =
    [ ("SET", [t| ByteString |])
    , ("ENUM", [t| ByteString |])
    ]

defineTable :: String -> String -> Q [Dec]
defineTable schemaName tableName =
  defineTableFromDB
    connect
    (driverMySQL { driverConfig = defaultConfig { normalizedTableName = False }
                 , typeMap = typeMap
                 })
    schemaName
    tableName
    [''Show,]

-- データベースとの接続に使うタイムゾーンを指定する必要がある。
dbTimeZone :: TimeZone
dbTimeZone = hoursToTimeZone 9

-- relational-query-0.9.4.1 では、ShowConstantTermsSQL POSIXTime のインスタンスが定義されていないため、自分で定義する必要がありそう。
instance ShowConstantTermsSQL POSIXTime where
    showConstantTermsSQL' = showConstantTermsSQL' . utcToLocalTime dbTimeZone . posixSecondsToUTCTime

Main.hs は以下のようになる。

{-# LANGUAGE FlexibleContexts #-}

module Main where

import GHC.Int (Int32)
import Database.HDBC (disconnect)
import Database.HDBC.Record (runQuery')
-- Database.Relational.Query は廃用になった
import Database.Relational

import DataSource

hello :: Relation () (Int32, String)
hello = relation $ pure (value 0 >< value "Hello")

main :: IO ()
main = do
  conn <- connect
  putStrLn $ "SQL: " ++ show hello
  result <- runQuery' conn (relationalQuery hello) ()
  mapM_ print result
  disconnect conn

ここで、遅延評価版の runQuery ではなく runQuery' を使わないと、複数のクエリを発行した際に死ぬことがあるので注意すること。

その他嵌った点

COUNT の引数として列を一つ渡すことに気を付けなければならないようだ。

-- これは駄目
numberOfFruitsWrong :: (MonadQualify ConfigureQuery m) => m (Record Flat (Maybe Int64))
numberOfFruitsWrong = queryScalar $ aggregatedUnique (relation $ query fruit) id' count

-- こうする
numberOfFruits :: (MonadQualify ConfigureQuery m) => m (Record Flat (Maybe Int64))
numberOfFruits = queryScalar $ aggregatedUnique (relation $ query fruit >>= \j -> return (j ! Fruit.id')) id' count