モーレツ! Org mode 教室 その8: org-journalで日記を書く

情けないことに、三日坊主どころか二日日記が続いた試しがなかったのだが、 org-journal を使い始めてからどうにかこうにか続いている。今回はその話をしたい。

設定は簡単で、 ~/.emacs.d/init.d

(use-package org-journal
  :ensure t
  :defer t
  :custom
  (org-journal-dir “~/Dropbox/Org/journal”)
  (org-journal-date-format “%A, %d %B %Y”))

などと書けば良い。

C-c C-j と打てば、 org-journal-dir で指定したディレクトリの下に、 20190225 といった具合に日付がファイル名となったファイルが作成される(すでにあれば、新しいエントリが挿入される)。後は普通にOrg記法で日記を書くだけである。前回書いた日記を見るには C-c C-b 、検索は C-c C-s だ。 org-journal-enable-encryptt にしてやれば、 org-crypt による暗号化もできる。

Emacsの calendar との連携もバッチリで、 M-x calendar でカレンダーを起動した後、日付の上で C-j を押すとその日のエントリが表示される。

以前紹介した org-capture で使うには、ややトリッキーだが

(defun org-journal-find-location ()
  (org-journal-new-entry t)
  (goto-char (point-min)))

(setq org-capture-templates '(("j" "Journal entry" entry (function org-journal-find-location)
                               "* %(format-time-string org-journal-time-format)%^{Title}\n%i%?")))

などとしてやれば、 C-c c j でメモやTODOと同じ感覚で日記が書けるようになる。これもまた便利である。他にもいろいろ機能があるが、それは org-journal のウェブページを見てもらいたい。

なんといいますか、あまりに自然に使えるので、あまり書くことがないのだが、おすすめですよ。

 

ステッドラー ザ・ペンシル

ステッドラー The Pencil Set タッチペン付き鉛筆3本セット

ここ数年ドイツ・ベルリンへ行く機会が多いのだが、今年もライプチヒでの35c3(The 35th Chaos Communication Congress)からの帰りに立ち寄った。以前このブログで書いた通り、ベルリンではKaDeWeという伊勢丹的なデパートへ行ってお土産を買うことが多いのだが(今回は年末だけにすさまじい混み具合だった)、店内をふらふらしていたらうっかりこれを見つけてしまったのである。29.90ユーロですから4000円くらいですか。
意味不明に高価な鉛筆といえばファーバーカステルのパーフェクト・ペンシルが有名だが、同じドイツのステッドラーが数年前、対抗馬として出したのがこのザ・ペンシルである。私は4年前、やはりベルリンのKaDeWeでパーフェクト・ペンシルUFOをうっかり買ってしまい、自分の馬鹿さ加減に嫌気が差したのだが、今回また似たようなものを買ってしまったわけで、自己嫌悪はいよいよ深まるばかりなのである。
製図用品や事務用品だけではじり貧と思ったのか、このところステッドラーはステッドラー・プレミアムと称する高級路線に舵を切って頑張っているのだが、これもその一環だったのでしょう。デザインではエレガントさを全面に押し出したファーバーカステルに対して、モダンといいますか、バウハウス的な味が強いのがステッドラー・プレミアムの特徴だが、今ひとつ垢抜けていないような気がするなあ。
エクステンダーにもなる鉛筆削りが付いてくる、というのはパーフェクト・ペンシルと同じだが、ステッドラーが誇る新世代ウォペックス鉛筆ベースというのがウリなんですかねえ。個人的には、減りも遅いし書き心地は柔らかくて好みなんだが、黒の発色がやや薄いような気がする。
いずれにせよ、

ちなみにステッドラーも対抗して(?)ザ・ペンシルという似たようなのを出しているようだが、うーん、スタイラスペンになると言われても…。というか、スタイラスペンになるナントカというのは結構あるが、そんなにみんなスタイラスペンを使っているの?

という4年前のわたくしの疑問に答えられる自信はない。
そんなわけで、あけましておめでとうございます。今年もよろしく。
追記 あとで鉛筆を削ろうとして気づいたのだが、エクステンダの下をひねることで削りカスが出てくるスリットが開閉できるので、カスを溜めておけるのですね。パーフェクト・ペンシルよりも機能面では上回っているなあ(笑)

 

児童ポルノの表現規制に関する考え方のスケッチ

はじめに

漫画やアニメ等の表現規制派の旗頭の一人で、東京都青少年問題協議会委員等の公職にも就いていたメディア学者、渡辺真由子氏の著書「『創作子どもポルノ』と子どもの人権」に、剽窃があるとのことで出版社が回収する騒ぎとなった。そのおかげで、というのも妙な話だが、渡辺が言うところの「創作子どもポルノ」、一般的には非実在児童ポルノとか準児童ポルノと呼ばれていると思うが、そうしたものの表現規制に関する議論が再浮上した感がある。

私が関わるMIAUは、2008年に起きた日本ユニセフ協会による準児童ポルノ騒動以来、長年に渡ってこの問題に深くコミットしてきたが、正直言って私自身はこの手の問題に専門的知見があるわけではない。そんなわけで、自分の頭の整理を兼ねて児童ポルノの表現規制に関する考え方をまとめてみた。似たようなことはすでに多くの人が書いているので、ようは個人的なメモである。

表現規制は結局法規制の問題に帰着するので、法学的、法制史的、あるいは国際比較法的な議論が重要だとは思うが、ここではできるだけ法的議論には踏み込まないという方針でやってみたい。素朴なロジックの範囲でどう考えられるか、というのがテーマだ。

不可侵原則と他者危害原則

表現規制を巡る議論が不毛になりがちなのは、規制派と反対派で前提を共有していないからではないかと思う。そこで、最初に私自身の前提というか考え方を明らかにしておきたい。

私がこの手の問題を考える際に基本とするのは、Non-aggression principle である。英語圏では NAP としてよく知られているが、日本語の定訳は無いようだ。以下では、やや座りの悪い訳だが「不可侵原則」ということにしたい。

これは、「同意が無い限り、他者を侵害してはならない」という立場のことである。ここでの侵害(aggression)とは、他者の所有権や決定権を強制的に犯したり、犯すと脅迫する行為全般のことを指す。我々の身体や能力には自己所有権や自己決定権が及ぶと考えられるので、当然、(性)暴力等も侵害となる。一方、外科医が患者の開腹手術を行うのと、殺人鬼が被害者の腹をナイフで裂くのは、外形的にはあまり違いがない。そこで、同意(consent)の質と有無が重要となるわけだ。当然同意主体には成熟した判断能力が必要とされるので、未成熟な児童の「同意」は、最低でも割り引いて評価しなければならないだろう。これが、年齢によるレーティングが正当化される根拠である。

これと表裏一体なのが(というか、出所は同じなので同じものと見なしてもよいのだが)、他者危害原則(Harm principle)である。これは、「他者への危害は、他者からの危害を防ぐ自衛の場合のみ正当化しうる」という立場である。Harmは危害と訳されることが多いが、相手を危険にさらすような行為だけではなく、より広い意味での干渉や介入全般を意味する。

裏を返せば、他者を侵害しない限り、他人から見てどんなに馬鹿で不道徳なことをしようと干渉されるいわれはなく、個人の自由、という立場でもある。不可侵原則や他者危害原則は不干渉原則でもあり、愚行権とも表裏一体なのだ。

その背景には、自分のことは自分が一番よく分かっているのであって、情報という点でも利害という点でも劣る他人があれこれ言うべきではない、という考え方もあれば、長期的に見ればさすがにいつかは自分のやっていることの馬鹿さ加減に気づくだろう、という人間の理性への信頼もあるだろうし、逆に、いつまで経っても人間は不合理で不道徳なことをやりたがる生き物で、遺憾ながらそれは人間性というものと深く結びついている、という諦念もあるだろう。愚行というとあまりイメージが良くないかもしれないが、私自身は、愚行権こそが人間の自由を保障する最後の砦であり、イノベーションの源泉だと考えている。

不可侵原則や他者危害原則に、正当性は認められるだろうか。不可侵原則に正当性がないとすれば、同意無しでも他者への侵害は認められるということになる。常識的に考えれば、これは殺人や暴力はもとより、奴隷制度や臓器くじを認めるという立場であり、現在多くの支持を得られるとは思えない。とはいえ、確かに緊急避難のような例外的ケースはあり得る。しかしそうした例外を認めるに当たっては、データに基づいた、誰の目から見ても明らかというレベルの強力な根拠が必要だろう。

他者危害原則に関しても様々な正当化が出来ると思うが、私としては、愚行権が認められない社会では愚行が出来ず、愚行したい人の自己決定権が侵害される一方、愚行権を認める社会では当然愚行をしない自由もあるわけで、パレート改善というか、最大多数の最大幸福という見地から正当化しうると思う。また、この考え方から導かれる、「する自由」対「しない/させない自由」といった価値観の衝突の解決法は、棲み分け、すなわちゾーニングということになるだろう。見たい人は見る自由、見たくない人は見ない自由を、それほど多大なコストをかけずに行使できる社会ということである。

実在児童ポルノと非実在児童ポルノ

以上の議論に基づき児童ポルノの問題を考えると、まず実在する児童を撮影した実在児童ポルノについては、その児童の自己所有権が明らかに侵害されているわけだから、全く容認の余地がない。実際、世界的に見ても、実在児童ポルノを擁護する声というのは皆無ではないかと思う。日夜、実在の人身売買や児童虐待と戦っている人々が多くいる。以前、スウェーデンにおける非実在児童ポルノを巡る裁判においてスウェーデン警察が、

一方、児童ポルノの摘発に力を入れるスウェーデン警察は、「性的虐待にさらされる恐れのある子どもたちを、空想のイラストと同レベルに扱うべきではない」と批判。既に警察は虐待の加害者の取り締まりで手一杯で、同裁判の焦点は児童ポルノ対策から外れているとして、「イラストまで捜査対象に加えれば、被害に遭っている子どもたちを助けるための時間が削られてしまう」との見解を示している。

述べたそうだが、これは児童ポルノ取り締まりの現実を雄弁に物語っている。

加えて、そもそもそれは本当に実在児童ポルノなのか、というのは慎重に検討する必要があろう。日本人を含むアジア人は、欧米人からは実年齢よりも若く見えるという。この場合、被写体は実は児童ではなく、同意が有効である可能性があるわけだ。実際、かつて30代の日本人グラビア女優の画像が、海外で児童ポルノ扱いされるという珍事件もあった。

では、漫画やアニメ等の非実在児童ポルノはどうか。

とりあえず、実在する児童のポルノ写真をトレースし、絵画だと言い張る者がいたが、これは実在児童ポルノの範疇であろう。

そうではなく、完全にイマジネーションに基づいたキャラクターが描かれた、非実在児童ポルノはどうだろうか。非実在のキャラクターなので、被害者は存在しない(そもそも「児童」なのか、あるいは人間なのかすらも分からない)。そもそも侵害される他者が存在しないのだから、不可侵原則にも他者危害原則にも抵触しないということになる。児童ポルノを見たり描いたりすることへの倫理的、宗教的批判はありうるかもしれないが、それは法的責任とは別の話で、結局は個人の愚行権の範囲内、というのがこれまでの議論から導かれる結論だと思う。

基本的にはこれで話が終わってしまうと思うのだが、それでもなお非実在児童ポルノを規制したいという場合、どのような論理が考えられるだろうか。今までの議論からすれば、最低でもこの場合、他者への侵害が何らかの形で確かに存在する、ということを、説得力ある形で示す必要が出てくる。

一つの方向は、非実在児童ポルノを見ることが、実在の児童虐待や児童性暴力といった犯罪行為を明らかに増加させるということの証明である。メディアを見ればなにがしか影響されるのは当たり前だが、それが実際に犯罪行為を誘発するかは話が別だ。この因果関係が証明されるのであれば、非実在ポルノの規制は予防措置としてある程度正当化できるかもしれない。

この点に関し、ブログで渡辺真由子氏自身のこれまでの研究を再検討した人がいるが、結局渡辺自身も含め、誰も因果は証明できていないようである。今後この分野の一層の研究が待たれるところだろう。とはいえ、個人的には、そもそもフィクション程度に安易に影響されて犯罪に走らないよう、性教育、メディア・リテラシー教育を充実させるほうがはるかに生産的だと思うが…。

もう一つの方向は、非実在児童ポルノの存在により、具体的に実在の児童の「何か」が侵害されるのだ、ということを、説得力ある形で示すことではないかと思う。渡辺の前掲書は、タイトルからするとそもそもはそれが狙いだったのではないかと思われるのだが、批判サイトを見る限りでは、「何か」が何なのか定義することに失敗しているようである。渡辺としては、それは「人権」だと言いたいようなのだが、非実在児童ポルノと実在の児童は何の関係もないわけで、かといっていわゆる集団的人権説を採るわけでもなく、かなり無理のある主張のように思われる。

 

戦場ジャーナリストと自己責任

シリアで長年武装勢力の人質になっていたジャーナリスト、安田純平氏が解放されたというニュースを受けて、日本のマスメディアでは様々な論評が出ているようだ。個人的には、毎日新聞の記事「<安田さん解放>『自己責任論』に海外経験者ら反論投稿」に違和感を感じた。

というのも、記事に「識者は『海外では唱えられることのない自己責任論が蔓延している状況を懸念」とあるのだが、拘束された戦場ジャーナリストに対し、自己責任の観点から批判が浴びせられることは海外でも決して珍しくないと思われるからである。ついでに言えば、この記事に出てくる人々は別にそんなこと言ってないような…。

例えば、アフガニスタン紛争では多くの欧米ジャーナリストが拉致、拘束されたが、2009年9月には、ニューヨーク・タイムズ紙に所属するイギリス人ジャーナリスト、スティーヴン・ファレルがタリバーン兵士に拘束されるという事件があった。4日後、イギリス軍の空挺部隊がタリバーンの隠れ家を急襲し、ファレル自身は救出されたが、戦闘では彼の通訳、アフガン人の女性と子供、タリバーン兵士らに加え、イギリス軍の兵士も犠牲となった。

ファレルの一行は、そもそもタリバーンの強固な拠点であり、NATOに爆撃されて多数の民間人死傷者が出た直後で殺気立っているアフガニスタン・クンドゥズの近郊に入り、そこでタリバーンに捕まったのだが、テレグラフ紙の記事によれば、アフガンの警察や情報機関には繰り返し危険を警告され、さらには取材した現地の長老にもタリバーンが近づいているから早く逃げろと言われたにも関わらず、現地に留まって拘束されたのだという。

後日、ニューヨーク・タイムズはファレルの件の検証記事を発表したが、その中でタイムズ自身がファレルへの様々な批判を紹介している。例えばデイリー・メイル紙は、「ジャーナリストの栄光への欲望と高すぎるリスク」と題してファレルを批判する記事を掲載した。読者からも、「ジャーナリスト一人を救うのに何という浪費か」、あるいは「世界の危険で不便な場所からの報道はもっとあってしかるべきだが、しかし拘束されたジャーナリストが最も賢明なやり方をとっていたといえるのだろうか?」などという疑問が呈されたという。また、前掲のテレグラフ紙の記事ではイギリス軍高官の話として、「ファレルが受けた警告の数を考えると、この男を救助する価値があったのか、救助で若いイギリス軍兵士が死ぬ価値があったのかと考え込んでしまう。今後似たような事例があった場合、特殊部隊の投入には再考の余地があるかもしれない」と報じている。また別のイギリス軍情報筋は、「このリポーターはアフガン警察の助言を無視してこのエリアに入った。ありがとうスティーヴン・ファレル、お前の無責任な行動のせいで我々の兵士が一人死んだのだ」と吐き捨てたという。

私は、(戦場)ジャーナリズムの意義を高く評価している。また、自国民保護はどのようなケースであっても国の責務だと考える。当時の英外相デイヴィッド・ミリバンドにしても、ファレルが度重なる警告を無視したのは遺憾としつつ、救出作戦を行ったこと自体は特に問題視していない。しかし、危険と分かっている地域に踏み込んで、それで無事に帰ってきたなら良いけれども、失敗して拘束され、他人に迷惑をかけた場合は、少なくともいくばくかの自己責任はあるだろうし、批判も甘んじて受けざるを得ないと思うのである。

ちなみに、テレグラフはおそらくイギリス政府からの情報を基に記事を書いているが、ニューヨーク・タイムズの記事では、途中のアフガン警察の検問でも止められなかったし、警告もされず、アフガン人スタッフも大丈夫だと判断したと述べており、食い違いがある。現地人とのやりとりを担っていた通訳が死んでしまったので、真相は藪の中なのだが。

安田氏が生還したこと自体は非常に喜ばしい。しかし、それと安田氏の取材計画に問題が無かったかは話が別で、今後慎重に問われるべきだろう。いずれにせよ、ファレルの例を見ても分かるように、戦場ジャーナリストの自己責任を問うべきではないなどというのは、洋の内外を問わず常識とは言えないと思う。

 

モーレツ! Org mode 教室 その7: org2blog で WordPress に投稿する

Org mode でブログを書きたい

Org modeに慣れてくるとなんでも Org modeで書きたくなってくるもので、ブログも Org 記法で書きたいのである。本ブログのような WordPress ベースのシステムでこれを実現するのが org2blog で、XML-RPC を使って Emacs からウェブなどを介さず直に WordPress へ投稿する手段を提供してくれる。XML-RPC (というか MetaWeblog API)ベースなので、Wordpress 以外の CMS でもおそらく使えるとは思うが(名前も org2 blog だし)、基本的には WordPress が想定されているようである。SOAPだJSON-RPCだというご時世にXML-RPCというのはやや古風だが、ちゃんと動く。

例によって org2blog もすでに MELPA レポジトリに入っているので、前回説明した straight.el と use-package の組み合わせで手軽にインストールできる…はずなのだが、残念ながら若干の小細工が必要だ。

org2blog のインストール

話の前提として、Wordpress の XML-RPC インターフェースにアクセスできなければならない。最近では脆弱性対策ということでサーバのほうでアクセスが制限されていることが多いので、これから org2blog を使うというマシンから、Wordpressを入れたディレクトリの直下にある xmlrpc.php にウェブブラウザからアクセスできることを確認すると良い(「XML-RPC server accepts POST requests only.」と表示されるはず)。おそらくhttp://www.yourblog.com/xmlrpc.php といった感じのURLで、WordPress.com のブログホスティングでも同じである。もちろん強いパスワードを設定し、アクセスできるIPアドレスを絞るなどの対策はしておくべきだろう。

さて、org2blog そのものには特に問題ないのだが、org2blog が中で使っている xml-rpc-el の現在のバージョンには若干問題があり、日本語のような Unicode キャラクタを含むリクエストがエラーになってしまう。そこで、早速前回紹介した straight.el の出番となる。直したバージョンを自分の Github レポジトリで公開している人がいるので、オフィシャルではなくそちらを使ってインストールするわけだ。具体的には、org2blog に関する記述の前に、init.el に

(straight-use-package
 '(xml-rpc-el :type git :host github :repo "grettke/xml-rpc-el"))
(use-package xml-rpc
  :defer t  
  )

などと書くだけでよい。

org2blog そのものの設定は、最小限で

(use-package org2blog
  :after org
  :defer t
  :config
  (setq org2blog/wp-blog-alist
        `(("myblog"
           :url "https://www.yourwordpresshost.com/xmlrpc.php"
           :username ,(car (auth-source-user-and-password "myblog"))
           :password ,(cadr (auth-source-user-and-password "myblog"))
           )
          ))
  (setq org2blog/wp-buffer-template
        "#+TITLE: 
#+CATEGORY: 
#+TAGS: 
#+OPTIONS:
#+PERMALINK: \n")
  )

こんな感じになるだろうか。 細かい説明は不要だと思うが、 wp-blog-alist には当然複数のブログを設定することもできる。

auth-source を用いた認証

問題は認証で、ユーザ名とパスワードを与える必要があるわけだが、流石に平文で init.el に書きこむのは気が引ける。そんなときは、Emacs 標準の認証管理機能である auth-source を使うと良いだろう。具体的には、~/.authinfo というファイルを用意し、

machine myblog login WordPressのユーザ名 password WordPressのパスワード

などと書いた上で、

$ gpg -c .authinfo

と GnuPG で暗号化して ~/.authinfo.gpg として置いておけばよい。あとは、 必要なときに auth-source が pinentry のようなパスフレーズ入力ダイアログを呼び出すので、そこから復号化できる。GPG は、Windows でも gpg4win などをインストールすれば普通に使えるだろう。org2blog を毎回使うわけではないのに起動時に毎回 GPG のパスフレーズを聞いてきて面倒くさいという場合は、上記の例のように (use-package org2blog):defer t を指定してやれば、必要なときまで読み込みが遅延されるので、パスフレーズ入力用ダイアログも org2blog の起動時に呼び出されるようになる。

org2blog でブログを書く

ここまで設定した上で、 M-x org2blog/wp-login を実行すると、Wordpress にログインして準備完了となる。あとは、 M-x org2blog/wp-new-entry を実行するとドラフトバッファが準備される。このドラフトのひな形を指定しているのが org2blog/wp-buffer-template だ。Org mode は、ファイル(というかバッファ)に #+FOO: bar という形式で書くことで、ファイル毎に細かく設定を変える仕組みがあるのだが(詳しくはThe Org Manual: In-buffer settingを参照)、ここではWordpressの記事のタイトルやパーマリンクを指定するのに使われている。 #+DATE: を使えば公開日時も指定できる。

ここまで来れば、後は Org 記法で記事を書くだけだ。書くにあたって記法に全く制限はなく、リンクを張ればリンクとして扱われるし、画像ファイルへリンクを張れば自動的にアップロードされる。書き終わったら、 M-x org2blog/wp-post-buffer でドラフトがサーバに送られ、希望すればウェブブラウザを呼び出してプレビューも見られる。もちろんいきなり公開することも可能だ。

ちなみに一度サーバに記事が送られると、ドラフトバッファには先ほどの In-buffer setting の一つとして #+POSTID: 数字 という行が追記される。これがあれば、Emacs 側で追記や編集をした上でまた M-x org2blog/wp-post-buffer を実行すれば、記事がダブることなくちゃんとサーバ側も変更に追従してアップデートされるのである。他にも、サブツリー単位で送信したり MathJax を用いた数式を書いたりといろいろなことが出来るのだが、細かいコマンド等は org2blog の Gihub レポジトリにある説明を参照してほしい。

いずれにせよ、org2blog を使うと WordPress のウェブインターフェースからちまちまパーマリンクやらタグやらを入力する必要がなくなり、まあ大したことではないのだが、気分的には大変楽である。Wordpress をお使いならぜひお試しください。

 

モーレツ! Org mode 教室 その6: straight.el で Org mode をインストールする

straight.el と use-package を使ったパッケージ管理

厳密にはOrg mode特有の話ではないのだが、最近のEmacsのパッケージ管理について。

Emacsは、Emacs Lispで書かれたパッケージを導入することで柔軟に機能を拡張できる。大昔はEmacs Lispのファイルをひとつひとつ手で落としてきて設定していたのだが、しばらく前からはpackage.elを使い、パッケージ間の依存関係に従ってMELPAのようなパッケージ・アーカイヴから芋づる式に自動インストール、といった管理が主流になった。さらに最近では、Caskel-getBorgQuelpaなど様々なパッケージマネージャが登場している。

なぜそういうことになるかというと要はどれも一長一短あるからだが、比較的最近開発されたstraight.elは先行する他のパッケージマネージャをよく研究していて、なかなか筋が良い設計になっている。私自身ここ数年 Cask を使っていたのだが、つい最近straight.elに乗り換えた。というわけで、その紹介をしたい。

straight.el のインストール

先日の記事でもちらっと書いたが、 Cask は実装がEmacs Lispで完結しておらず、 Cask 自体のインストールにPythonが必要だった。最近では大概のシステムにPythonが入っているので、ある意味どうでもいいとは言えるのだが、Windowsなどではひと手間増えてしまうのは間違いない。一方 straight.el はパッケージの管理にGitが必要だが、インストールそのものは ~/.emacs.d/init.el に以下を書いてEmacsを起動するだけである(これは el-get も同じだが)。

;; straight.el のインストール
(defvar bootstrap-version)
(let ((bootstrap-file
       (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
      (bootstrap-version 5))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
        (url-retrieve-synchronously
         "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
         'silent 'inhibit-cookies)
      (goto-char (point-max))
      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))

ようはGithubのstraight.elのレポジトリからinstall.elを落としてきて、それを実行しているわけですね。 straight.el 関係の全ては基本的に ~/.emacs.d/straight の中にあるので、何かおかしくなったらこのディレクトリを消してやり直せばよい。

straight.el が好ましい点の一つは、use-packageと緊密に連携しているところである。 use-package に関しては日本語でも他に詳しい解説がいくらもあるのでそちらを参照してもらいたいが、大ざっぱに言えば、 ~/.emacs.d/init.el でのライブラリの読み込みや、起動時の遅延読み込みの設定が明快に書けるようになる便利なマクロだ。 (require 'foobar) と書き続けて数十年のオールドタイマーだと目が慣れるまでは違和感があると思うが、いったん要領を掴めば書き換えはそんなに手間ではない。

straight.eluse-package の連携を使うには、

(straight-use-package 'use-package)
(setq straight-use-package-by-default t)

と書いておく。このように設定すると、

(use-package foobar)

~/.emacs.d/init.el に書くだけで、MELPAなどのレポジトリから適当に foobar パッケージを落としてきてインストールしてくれるのである。しかも、 straight.el の場合落としてきたパッケージは ~/.emacs.d/straight/repos 以下にクローンされたGitレポジトリとして展開されているので、内容確認や手直しも簡単だ。なので straight.el にはパッケージのアップデートという概念はなく、fetchとかmergeとかpushなのである。

また、自分で手でインストールしたとか、Emacsと一緒に配布されていてダウンロードする必要がないというライブラリであれば、

(use-package foobar
  :straight nil)

と個別に straight.el 対応を無効にしてやればよい。あるいは、そのパッケージがMELPAにあるのは知っているが、MELPAのバージョンだと不具合があるので、他の人がGithubかどこか別のところで公開しているバージョンが使いたい、ということもあるだろう。そうした場合は、

(straight-use-package
 '(foobar :type git :host github :repo "mhatta/foobar"))
(use-package foobar)

とか、

(straight-use-package
 '(foobar :type git :host github :repo "upstream/foobar"
            :fork (:host github
                   :repo "mhatta/foobar")))

などとフォークを明示的に指定してインストールすることもできてしまうのである。他にも straight.el は、パッケージのバージョンを固定したりいろいろなことが出来るのだが、そのへんは例えば このあたりの記事を参照してもらいたい。

というわけで、straight.el を上手く使うと、例えば他のコンピュータにinit.elだけ持っていけば、あとは Emacs を起動するだけでパッケージのインストールから設定まで終わってしまうのである。これはとても便利だ。

straight.el を使った Org modeのインストール

さて、今まで基本的にはOrg modeの話をしてきたのに、なぜ straight.el について延々と書いているかと言えば、straight.el で Org modeをインストールするときに若干の小細工が必要になるからである。しばらく前からEmacs本体にOrg modeが同梱されているため、レポジトリから最新の Org をインストールしようというとき、システムには古いバージョンの Org が存在していてすでに読み込まれている、ということが避けられない。これがインストール時に思わぬ不具合をもたらすことがあるので、init.elに

;; straight.elによるorg modeのインストールに先立つ準備
(require 'subr-x)
(straight-use-package 'git)

(defun org-git-version ()
  "The Git version of org-mode.
Inserted by installing org-mode or when a release is made."
  (require 'git)
  (let ((git-repo (expand-file-name
                   "straight/repos/org/" user-emacs-directory)))
    (string-trim
     (git-run "describe"
              "--match=release\*"
              "--abbrev=6"
              "HEAD"))))

(defun org-release ()
  "The release version of org-mode.
Inserted by installing org-mode or when a release is made."
  (require 'git)
  (let ((git-repo (expand-file-name
                   "straight/repos/org/" user-emacs-directory)))
    (string-trim
     (string-remove-prefix
      "release_"
      (git-run "describe"
               "--match=release\*"
               "--abbrev=0"
               "HEAD")))))

(provide 'org-version)

;; 以下Org modeの設定
(use-package org)

などと書いておくとよい。ちなみに前回までの話を踏まえた Org の設定を use-package で書くと、

(use-package org
  ;; :defer t で起動時に Org を読み込まない(起動が速くなる)
  :defer t
  :config
  (setq org-directory "~/Dropbox/Org"
        org-default-notes-file "notes.org"
        org-agenda-files '("~/Dropbox/Org/gtd.org"
                           "~/Dropbox/Org/notes.org")
        org-log-done 'time
        org-startup-truncated nil
        org-use-speed-commands t
        org-enforce-todo-dependencies t)
  (setq org-todo-keywords
        '((sequence "TODO(t)" "SOMEDAY(s)" "WAITING(w)" "|" "DONE(d)" "CANCELED(c@)")))
  (setq org-refile-targets
        (quote ((nil :maxlevel . 3)
                (mhatta/org-buffer-files :maxlevel . 1)
                (org-agenda-files :maxlevel . 3))))
  (setq org-capture-templates
       '(("t" "Todo" entry (file+headline "~/Dropbox/Org/gtd.org" "INBOX")
         "* TODO %?\n %i\n %a")
        ("j" "Journal" entry (function org-journal-find-location)
         "* %(format-time-string org-journal-time-format)%^{Title}\n%i%?")
        ("n" "Note" entry (file+headline "~/Dropbox/Org/notes.org" "Notes")
         "* %?\nEntered on %U\n %i\n %a")
        ))
  ;; org-tempo
  ;; Org 9.1.14 では明示的に読み込む必要があるかも
  (use-package org-tempo
    :straight nil)
  :bind
  (("\C-ca" . org-agenda)
   ("\C-cc" . org-capture)
   ("\C-ch" . org-store-link))
  )

こんな感じになるのでしょうかねえ。

 

モーレツ! Org mode 教室 その5: TODOを管理する

もくじ

TODOの管理

Org modeには、強力なTODO管理機能が備わっている。

なんでアウトライン・プロセッサにTODO管理機能が付いてんだ、という疑問は当然あると思うが、確かにやるべきことというのは大体書き仕事をしているときに思いつくもので、そういう意味では文章執筆支援が本業のOrg modeにTODO機能があるというのはそんなにおかしくはない。実際、非常に便利である。

TODOを書くのは簡単で、とにかく見出しに続けて TODO と内容を書けばよい。

* TODO ゴミを出す

手でTODOと書いてもよいが、見出しの上で C-c C-t と打つと自動的に挿入される。さらに、何度か C-c C-t と打つとTODOとDONE(済み)、そしてただの見出しという風に切り替わるはずである。 S-右/左矢印 も基本的に同じ。

さらに S-上/下矢印 を押すと [#B] のような文字列が挿入される。これはTODOの優先度で、標準がBというわけである。もう一度押すとAやCに切り替わる。例によって S-M-RET で次行にTODO見出しが追加され、 M-上/下矢印 で行の順番が入れ替えられる。

* TODO [#A] 便所を掃除する
* TODO [#B] ゴミを出す

キーワードの追加

TODOの状態が、TODOとDONEだけなのが寂しいという人もいるかもしれない。例えばGTDの信奉者だと、Someday/MaybeやWaiting Forに相当する状態が欲しいという人もいるだろうが、そうした場合は

(setq org-todo-keywords
  '((sequence "TODO" "SOMEDAY" "WAITING" "|" "DONE")))

などと org-todo-keywords にキーワードを指定することで増やすことができる。 で、 C-c C-t を打つごとに次々と状態が切り替わる…のは良いのだが、キーワードが増えるといちいち一つずつ切り替えるのもめんどくさい。その場合は、

(setq org-todo-keywords
  '((sequence "TODO(t)" "SOMEDAY(s)" "WAITING(w)" "|" "DONE(d)")))

などと、キーワードの後に半角丸かっことショートカット文字を追加してやると、 C-c C-t と打てば、メニューが出てきてその文字を打つだけでキーワードが指定できるようになる。文字は好きに選べるので、例えばDONEに d ではなく x を当ててもいいわけだ。 | は装飾で、縦棒の右と左で色が変わる。好きなところに入れればよい。

私は装飾だと思っていたのだが、実は縦棒には実質的な意味があった!あとでまた触れる。

TODOの追加

さらに、メモの要領で思いついたTODOをすぐ保存できると便利である。その1で取り上げたOrg-captureを用いて、

; Org-captureのテンプレート(メニュー)の設定
(setq org-capture-templates
      '(("t" "Todo" entry (file+headline "~/ownCloud/Org/gtd.org" "INBOX")
     "* TODO %?\n %i\n %a")
    ("n" "Note" entry (file+headline "~/ownCloud/Org/notes.org" "Notes")
     "* %?\nEntered on %U\n %i\n %a")
    ))

のように書けば、 いつでもどこでも C-c c を押せばメニューが出現し、t を押せばTODO見出しが出てくる。で、書いたら C-c C-c ですぐ保存、やめたければ C-c C-k で破棄されるのである。

このセッティングだと、gtd.orgというファイルの * INBOX という見出しの下に ** TODO 借金を返す と言った感じで保存される。私はTODOはgtd.org、メモはnotes.orgと分けているが(refileできるのでファイルというかサブツリー間の移動はどのみち簡単)、別に分けなくてもよい。また、gtd.orgとかINBOXというのは私がGTDごっこをしているからで、名前はなんでもよい。

プロジェクト管理

プロジェクト管理というか、複数の小仕事からなる大仕事というのもあるが、Org modeはこれもうまくハンドルできる。

* TODO 世界を制服する [33%]
** DONE 日本を制服する
** TODO アメリカを制服する
** TODO 中国を制服する

といった具合に、TODOを入れ子にすることが出来るのである。 その3で出てきたチェックボックス同様、最上位のTODO見出し、これが実質的にプロジェクト名になるわけだが、ここに [/][%] と書いておけば、完了したTODOの数やパーセントも計算してくれる。

基本的にはこれで十分だと思うが、こだわるならばもう少し細かくコントロールすることもできる。

例えば、

* TODO 世界を制服する [0%]
** TODO 志を高く持つ
** TODO 世界各地を制服する
*** DONE 日本を制服する
*** TODO アメリカを制服する
*** TODO 中国を制服する

のように、子TODO(この場合、世界各地を制服する)の下にさらに孫TODO(例えば、日本を制服する)がある場合、デフォルトでは孫TODOを一つ潰しても全体の達成数や達成率にカウントされないのだが(だからこの例の場合0%)、

* TODO 世界を制服する [20%]
:PROPERTIES:
:COOKIE_DATA: todo recursive
:END:
** TODO 志を高く持つ
** TODO 世界各地を制服する
*** DONE 日本を制服する
*** TODO アメリカを制服する
*** TODO 中国を制服する

のように指定すると、子TODOが一つも終わっていないので0%、ではなく、子も孫もひっくるめて全部で5つのTODOのうち1つ終わったから20%終了、となる。

Org modeには見出しツリーの挙動を細かく変えられるプロパティという仕組みがあり、 :PROPERTIES::END: で囲った中でいろいろ指定できるのだが(詳しくは The Org Manual: Properties and columnsを参照)、 :COOKIE_DATA: というプロパティに todo recursive と指定してやると、孫TODOもカウントしてくれるようになるのである。

* TODO 世界を制服する [33%]
** DONE 日本を制服する
** TODO アメリカを制服する
** TODO 中国を制服する

最初の例に戻って、この場合デフォルトでは、日本以外を制服しなくてもとりあえず世界制服をDONEにすることが出来てしまうのだが、~/.emacs.d/init.el に

(setq org-enforce-todo-dependencies t)

と書いておけば、子TODOを全部クリアしないと親TODOをDONEに変えられなくなる。どうしても変えたい場合は C-u C-u C-u C-c C-t とすれば変えられる。好みにもよるだろうが、有効にしておくと良い機能である。

また、上から順にTODOをこなすことを強制したいのであれば、

* TODO 世界を制服する [20%]
:PROPERTIES:
:ORDERED: t
:END:   
** DONE 志を高く持つ
** TODO 超兵器を開発する
** TODO 日本を制服する
** TODO アメリカを制服する
** TODO 中国を制服する

などと指定してやると、超兵器を開発しない限り日本の制服以下をDONEにできないようになる。プロパティの :ORDERED: を t にすると、上から順にこなしていかなければならなくなるわけだ。

タイムスタンプの基本

Org modeでは、 C-c . を打つと簡単にタイムスタンプを挿入して時間を記録することができる。 今日の日付ならそのままEnterだし、カレンダーが出てくるので、他の日付を入れたければ S-矢印 で移動して好きな日付でEnterを打てば、<2018-08-27 月> といった感じに挿入される。タイムスタンプの上で C-c . を打つと編集できるし、うっかり編集しておかしくなった場合は、 C-c C-c を打てば自動的に修正される。

期日や締切、あるいは習慣のような繰り返されるTODOなど、タイムスタンプ機能は時間の流れを考慮に入れたスケジュール管理で最も活躍するのだが、そのあたりに関してはOrg-agendaの紹介をする際に譲り、今回の話に必要なものに絞ると、重要なのはTODOの終了日時の記録法である、~/.emacs.d/init.elに

(setq org-log-done 'time)

と指定すると、TODOをDONEにした際に、

* DONE ゴミを出す
  CLOSED: [2018-08-27 月 00:18]

などと終わった時刻が自動的に記録される。

で、実はこれとさっきの縦棒が絡んでくるのである。たとえば

(setq org-todo-keywords
  '((sequence "TODO(t)" "SOMEDAY(s)" "WAITING(w)" "|" "DONE(d)" "CANCELED(c@)")))

のようにすると、TODO、SOMEDAY、WAITINGはただキーワードが切り替わるというだけだが、DONEとCANCELEDは、DONE扱いといいますか、これらのキーワードに切り替えるとCLOSEDのタイムスタンプが自動的に挿入されるのである。すなわち、TODOには大別してOPEN状態とCLOSE状態があり、縦棒は、左がOPEN状態とみなされるキーワード、右がCLOSE状態とみなされるキーワードを分けていたのだった。

なお、CANCELEDのショートカットが (c@)になっているが、このように@をつけると、メモと同じ要領でそのキーワードにした理由を書くことができるようになる。

GTDぽい運用

GTDというのはGetting Things Doneの略で、まあ仕事術のようなものです(15分で分かるGTD – 仕事を成し遂げる技術の実用的ガイド)。Org modeが好きな人にはGTDが好きな人も多いようで、「Org mode GTD」などで検索すると佃煮にするほど多くのページが出てくる。

私の運用はGTDごっこというか、ごくシンプルなもので、

  1. TODOを思いついたらとりあえず C-c c t で記録する。Orgディレクトリのgtd.orgの * INBOX という見出しの下に保存される。

  2. 一日の終わりにでもgtd.orgを見返し、 複数のTODOをまとめてプロジェクトにしたり、C-c C-t で、他人のアクションを待っているTODOはWAITINGに、当面やるつもりはないがそのうちやりたいことはSOMEDAYに変えておく。

  3. あらかじめ gtd.orgに* Projects* Waiting* Someday という見出しを作っておき、それぞれrefileする。 一つずつ C-c C-w で=refileしてもよいし、TODOやらWAITINGやらSOMEDAYやら大量の見出しが入り混じっているのであれば、M-x org-sort でtodo[o]rderのoを選ぶと、たぶんキーワードごとに並べ替えられるので、あとはカット&ペーストで一度に移してやればよいと思う。

といった具合である。こうするとgtd.orgは、おそらく


* Inbox
** DONE ゴミを出す
   CLOSED: [2018-08-27 月 00:15]
** TODO 花に水をやる

* Projects
** TODO 本を書く [33%]
*** DONE 第1章を書く 
*** TODO 第2章を書く 
*** TODO 第3章を書く 

* Waiting
** WAITING 原稿の件を佐藤さんに連絡 ←これは佐藤さんからの連絡を待っているということ
   <2018-08-27 月> ←こちらから連絡した日時をタイムスタンプで記録しておくと便利

* Someday
** SOMEDAY 世界を制服する
*** TODO 超兵器を開発する
*** TODO 日本を制服する
*** TODO その他を制服する

こんな感じになるんじゃないでしょうかねえ。

 

モーレツ! Org mode 教室 その4: 画像を手軽に貼る

番外編というか、本当は先に別のことを書こうと思っていたのだが、人に聞かれた(そして私自身も知らなかった)ので、画像の貼り方について。

ウェブブラウザ等からドラッグ&ドロップでOrgファイルに画像を貼れると便利だが、どうしたらいいのかよく分からなかった。少し調べてみたところ、どうやらorg-downloadを使うとできそうだということが分かった。

例によってorg-downloadもMELPAにあるので、~/.emacs.d/init.el に

; melpa
(require 'package)
(add-to-list 'package-archives
        '("melpa" . "https://melpa.org/packages/"))
(package-initialize)

などと書き、 M-x list-packages で一覧から選んでi xを押すか、 M-x package-install で直接org-downloadを指定してインストールすればよい。

で、org-download自体の設定としては

; Org-download
(require 'org-download)
(setq-default org-download-image-dir "~/ownCloud/Org/pictures")

を追加する。MELPAからインストールした場合requireは要らないことが多いのだが、私の環境(Debian GNU/Linux)では必要だった。 org-download-image-dir で画像ファイルの保存先ディレクトリを指定する。

あとは適当な画像をEmacs内にドラッグ&ドロップするだけで、

#+DOWNLOADED: https://www.gnu.org/software/emacs/images/teaser.png @ 2018-08-23 21:56:20
[[file:Dropbox/Org/pictures/teaser_2018-08-23_21-56-20.png]]

などとコメントとリンクが挿入され、場合によっては画像がインライン表示される。画像ファイルは org-download-image-dir に保存される。Debian sidとWindows 10の両方で、Firefoxから貼れることを確認した。

画像がインライン表示されるかどうかはEmacsのビルド次第で、最近だとJPG形式やPNG形式なら基本的にはサポートされるはずである。Windows では、なぜかどんな画像もBMP形式で保存されてしまうようで、まあそれは別に構わないのだが、EmacsはImageMagickサポートを組み込まないとBMP形式を表示できないので注意が必要。

他にも org-download にはいくつか機能があり、例えばキルバッファに画像ファイル名やURLを入れた上で、 M-x org-download-yank を実行すると、ドラッグ&ドロップしたときと同様に画像が挿入される。何の役に立つんだという人もいるだろうが、実は Dired で画像ファイルの上で 0 w と打つとそのファイルの場所がキルバッファに入るので、すでにローカルにある画像を簡単に挿入することが出来るのである。また、M-x org-download-screenshotを実行し、適当なウィンドウ上でクリックすると、そのウィンドウのスクリーンショットが挿入される。

 

モーレツ! Org mode 教室 その3: 文章の見た目を修飾する


もくじ

Org modeは、文字や文章の修飾機能も豊富である。Emacs上での見た目にもそれなりに反映されるが、特に威力を発揮するのは、HTMLなど他の形式へのエクスポート(変換)においてだろう。

ちなみにいきなり余談だが、見出しの文字を大きくしたりしてOrg modeのEmacs上での見た目を多少改善する、 org-beautify-theme というEmacs テーマがある。現在、Emacsの拡張機能はMELPAというレポジトリに多く集まっていて、このorg-beautify-theme もそこにあるので、~/.emacs.d/init.el に

(require 'package)
(add-to-list 'package-archives
         '("melpa" . "https://melpa.org/packages/"))
(package-initialize)

を入れて前々回出てきたpackage-elのパッケージ取得先にMELPAを追加し、Emacsを再起動するか init.el を開いて M-x eval-buffer した上で、 M-x package-install でorg-beautify-themeを指定すれば簡単にインストールすることができる(もちろんM-x list-packagesから選んでインストールすることも可能)。その上で、 M-x load-theme org-beautify で試してみるとよい。なお、 * などのブレット文字をUTF-8の記号に置き換える org-bullets という拡張もある。

エクスポート

ということで、先にOrg 形式から他フォーマットへのエクスポートのやり方を説明しておくと、ようは C-c C-e である。これを打つとメニューが表示されるので、それを見ながら、例えばHTMLなら h, Markdownなら m と打ち、さらにもう一度同じ文字を打って出力先を選ぶと変換される。これら以外の形式を指定するやり方や、変換範囲の設定などもメニューに書いてある。またはThe Org Manual: Exportingを読むとよい。また、ドキュメント変換ツール Pandocを使う手もある。

Markdownとの比較

Orgの記法(Org Syntaxと呼ばれる)もいわゆる軽量マークアップ言語の一つだが、今どき軽量マークアップ言語と言えばやはりMarkdownだと思う。ということで、Markdownとの対照表を作ってみた。

修飾内容 Orgの記法 Markdownの記法
見出し * 見出し # 見出し
コメント # コメント <!– コメント –>
強調(太字) **強調(太字)** **強調(太字)**
斜体(イタリック) /斜体(イタリック)/ *斜体(イタリック)*
下線 _下線_ <u>下線</u>
打ち消し +打ち消し+ ~~打ち消し~~
インラインコード ~インラインコード~ `インラインコード`
見た目そのまま(文字は等幅) =そのまま= `そのまま`

コメントにするとエクスポートで出力されなくなる。

なお、段落は前後の空行で分けられる。強制的に改行したければ文末に2つ半角スペースを入れる。このへんもMarkdownと同じである。水平線はダッシュを最低5つ、 すなわち ----- である。3つ以上で良いMarkdownとは若干違う。


また、 = のようなマークアップに使われる文字の前後には、半角スペースを一つ入れないとうまく解釈されないことがある。Emacs上で色が変わっているか確認すると良い。全角カンマやピリオドの後などが要注意である。

リスト

Org modeのリスト(箇条書き)の扱いはなかなか優秀だ。文中の好きなところで、とにかく行頭から始めるかインデントを合わせ、 -+ といったいかにもブレットになりそうな文字を書き並べてそれっぽくすれば、箇条書きとして扱ってくれる。

- 項目1
  - 子項目1
  - 子項目2
- 項目2
  1) その1
  2) その2
- 項目3
  • 項目1
    • 子項目1
    • 子項目2
  • 項目2
    1. その1
    2. その2
  • 項目3

といった具合で、 1.1) から始めれば、順序のある箇条書きとなる。インデントを下げれば入れ子も可能。箇条書きの行のどれかの上で C-c - を押すと箇条書きのブレットが次々と変わるのでやってみるとよい。また、箇条書きの上で C-c を打つと、番号が振り直されるので便利である。

見出しと定義、というタイプのリストは、 :: で分ける。

- ラーメン :: 醤油、塩、味噌など
- カレー :: アルー・ゴビー、バラック・サブジ、ラジマなど
  • ラーメン: 醤油、塩、味噌など
  • カレー: アルー・ゴビー、バラック・サブジ、ラジマなど

といった具合。

また、箇条書きの行の上で M-RET を押せば下に新しい行が挿入される。 M-上矢印M-下矢印 で項目の順序を入れ替えることもできる。大体順番を入れ替えるのはこのコマンドである。ちなみに普通は見出しとして使われる * も、行頭にせず適当にインデントすればブレットとして扱われる(が、混乱するのでやめたほうが無難)。

さらに、箇条書きの行の上で M-S-RET を押すとチェックボックスが挿入される。

- 人としてやるべきこと [/]
  - [X] 盆栽に水をやる
  - [ ] 子孫に美田を残す
  - [ ] 借金を返す 
  • 人としてやるべきこと [1/3]
    • [X] 盆栽に水をやる
    • [ ] 子孫に美田を残す
    • [ ] 借金を返す

チェックボックス行の上で C-c を押すとチェックされ、もう一度押すと元に戻る。

また、見れば大体見当が付くだろうが、 [/] を書いて C-c を打つと、その下の箇条書きのチェックボックスの数を数えて表示してくれる。 [%] と書くとパーセント表示になる。

他にも細かな操作が可能なので、The Org Manual: Plain listsを読むとよい。

リンク

厳密には見栄えの問題ではないが、Org modeではリンクも簡単に張ることができる。そもそも https://www.mhatta.org/wp/ といった具合で、ただURLを書けばすぐにリンクになる。最初は面食らうかもしれない。

説明をつけたければ C-c C-l である。まずリンクを入力し、次いで説明を入力する。するとリンクが挿入される。私のブログ といった具合である。リンク上でもう一度 C-c C-l を打つと編集できる。また、リンク上で C-c C-o を押すとWWWのURLならブラウザ、PDFファイルならPDFビューワといった具合で、適切な手段で開いてくれる。

もちろんOrg modeなので、すべてはプレーンテキストで表現されている。

[[https://www.mhatta.org/wp/]]
または
[[https://www.mhatta.org/wp/][私のブログ]]

といった具合に書かれているわけで、これを手で書いても構わない。Markdownとはリンクと説明の順序が逆ですね。

実はウェブのリンク以外にも、ファイルやメール、学術論文のdoiへのリンクなども簡単に張ることができる。 C-c C-l の補完内容をチェックしてみてほしい。また、何かのファイルを開いて C-c l を打つと、行番号など位置情報も含めて適切なリンクを勝手に考えて保存してくれるので、それを C-c C-l で挿入できる。こんな具合でリンクも実は奥が深いというか泥沼なのだが、より詳しくは The Org Manual: Hyperlinks を見るとよい。

上付き文字、下付き文字、LaTeX

Org modeの愛用者には科学者が多いせいか、数式を記述するのに便利な機能も多い。いわゆる上付き文字、下付き文字はネイティヴにサポートされていて、たとえば x^{上付き}y_{下付き} といった具合に記述できる。科学で多用されるギリシャ文字も、 \alpha\beta のように記述できる。Emacs上ではただのプレーンテキストだが、HTML等にエクスポートすればそれなりの見た目になる。なおEmacs上でも、運が良ければ C-c C-x \ (最後は円マーク)を押すとがんばってレンダリングされるかもしれない。

もう少し複雑な数式となると、 \begin{}\end{} で囲ったり、 $ でくくったりすればLaTeXの記法がそのまま使える。例えば $y=\sqrt{x}$ といった具合である。例えばHTMLエクスポートだと、デフォルトではMathJaxでレンダリングされるので、LaTeX一式は必要ない。もちろんLaTeXにレンダリングを任せることもできる。

表のサポートはOrg mode最大のダークサイドで、といっても出来が悪いのではなくむしろ意味不明に高機能であって、表計算やプロット、果ては高度な科学計算まで出来て頭がおかしい感じなのだが、機会があれば別途もう少し詳しく説明したい。そんなわけで、ここでは最低限に留めるが、より詳しくは The Org Manual: Tables を見てもらいたい。

といっても書き方自体としてはあまり説明することはなく、ASCII文字を駆使して表っぽく書けば表として扱ってくれるのである。基本としては、 | で区切ってデータを入力していけばよい。また、行の最初で |- などと入力して TAB を打つと、グラフの横幅まで横線が引かれる(一番下の横線は、 C-c - で引ける)。例によって表の要素は M-矢印 で移動できる。

とにかくわからなくなったら TABC-c を押せば適当に整形してくれるはずである。Org mode上での見た目はしょぼいが、HTML等にエクスポートすればそれなりに見栄えのする表にしてくれる。

|--------+------+------+------+------|
| 氏名   | 数学 | 英語 | 国語 | 合計 |
|--------+------+------+------+------|
| 野比   |    5 |   20 |   50 |      |
|--------+------+------+------+------|
| 出来杉 |   80 |   80 |   80 |      |
|--------+------+------+------+------|
氏名 数学 英語 国語 合計
野比 5 20 50  
出来杉 80 80 80  

さらに、野比の合計欄(2行目・5列目)で C-c = を打つと、 Column formula for $5 と聞いてくるので、 vsum($2..$4) などと入力してやると、野比の合計が計算される。また、下に追加される #+TBLFM の行の上で C-c を打つと表全体が再計算され、出来杉の合計も計算される。いわゆる表計算が出来るのである。

|--------+------+------+------+------|
| 氏名   | 数学 | 英語 | 国語 | 合計 |
|--------+------+------+------+------|
| 野比   |    5 |   20 |   50 |   75 |
|--------+------+------+------+------|
| 出来杉 |   80 |   80 |   80 |  240 |
|--------+------+------+------+------|
#+TBLFM: $5=vsum($2..$4)
氏名 数学 英語 国語 合計
野比 5 20 50 75
出来杉 80 80 80 240

すでにお察しの通り、行が @ 、列が $ で表現されていて、ピリオド2つで範囲を指定する。 vsum() はEmacsの知られざる黒魔術の一つである Emacs Calc (名前は Calc だが実際の機能は Mathematica 並み)の関数だ。ということで、ここから先は魅惑の泥沼が広がっている。

なお、あらかじめヨコ5×タテ2などとサイズが決まっている場合は、 C-c | を打ってそう指定すればそのサイズの表を用意してくれる。さらに、CSVで

氏名,数学,英語,国語,合計
野比,5,20,50,75
出来杉,80,80,80,240

などと書いて、リージョンとして選択した上で C-c | を押すと、表にしてくれたりもするのである。 M-x org-table-import を使うとファイルからインポートすることもできる。

引用やコード等の挿入

まず、行頭に : を書くと、マークアップを無視してそのまま表示される。Markdownで言うところの4文字スペースインデントに相当。

: いわゆる verbatim 表示。
: **強調** などのマークアップが無視される。
: 改行は無視されない。
いわゆる verbatim 表示。
**強調** などのマークアップが無視される。
改行は無視されない。

また、Org にはブロックという概念があり、 #+BEGIN_ブロックの種類#+END_ブロックの種類 で囲うと、そこがひとまとまりとして扱われる。例えば引用は、

#+BEGIN_QUOTE
鳴かぬなら殺してしまえホトトギス -- 織田信長
#+END_QUOTE

鳴かぬなら殺してしまえホトトギス – 織田信長

といった具合で、左と右にマージンが設定される。Markdownで言えば>である。

シャープ、プラス、ビギンなどといちいち入力するのは面倒だという人もいるだろうが、実は Easy Templates という機能のおかげで <q と入力して TAB を押すと補完入力されるので、そうでもない。QUOTEのqですね。

例は #+BEGIN_EXAMPLE から #+END_EXAMPLE である。これも、 <e と入力して TAB で補完される。EXAMPLEのeですね。

#+BEGIN_EXAMPLE
例の例の例。**お元気**ですか。
#+END_EXAMPLE
例の例の例。**お元気**ですか。

これは実質的には verbatim 表示と同じで、ブロック内のマークアップが無効となる。

ソースコードを引用したければ、 #+BEGIN_SRC から #+END_SRC である。これも、 <s と入力して TAB で補完される。SRCのsである。さらに、 #+BEGIN_SRC のうしろに言語名を書くと、言語の文法に従って適切にハイライト表示されるし、エクスポートでも考慮される。このあたりもMarkdownの ``` と同じだ。

#+BEGIN_SRC emacs-lisp
(defun xor (a b)
     "Exclusive or."
     (if a (not b) b))
#+END_SRC
(defun xor (a b)
     "Exclusive or."
     (if a (not b) b))

ちなみに、 #+BEGIN_SRC の後ろで C-M-i を押すと、Org modeが対応している言語の一覧が出てくるので簡単に指定できる。

さらに、Org modeには Org-babel という機能があり、コードブロック内のコードをOrg modeの中から実行できるのだが(PythonやらC++やらGNU Rはもとより、シェルスクリプトも書けるし、SSH経由で遠隔操作できたりもする)、それはまたそのうち。

 

モーレツ! Org mode 教室 その2: まとまった文章を書く


もくじ

前回も書いたように、Org modeは機能が増えすぎて今やなんだか訳のわからないものになっているが、本業はあくまでアウトライン・プロセッサ(英語圏ではアウトライナーと言うらしい)であって、アウトラインで構造化された文章を書くための道具として開発されたのである。

アウトラインとは、大ざっぱに言ってしまえば見出しのことで、大見出しで大まかな話、中見出しで少し細かい話、小見出しで詳細…という具合に、見出しの階層と内容の細かさを対応させて整理された文章を書く、というのがアウトライン・ライティングの狙いであった。Org modeには、このための支援機能が大量に備わっている。

追加の設定

Org modeは、.orgというという拡張子のついたファイルを開くと自動的に有効になる。まあ、M-x org-modeを実行すればどのバッファでも有効になるので、どうでもいいとも言えるが。

好みによるのかもしれないが、Org modeで長い文章を書く場合、~/.emacs.d/init.el

(setq org-startup-truncated nil)

を入れたほうがよいのではないかと思う。これは行の折返し(line wrapping)の設定で、Org modeはデフォルトでは行を折り返さないのである。手で適当に改行して一行を短くするか、適宜M-qで段落を詰め込めばよいのだろうが、私の場合だらだら改行を入れずに書いていくことが多く、カーソルがどんどん右に移動して文章の最初のほうが見えなくなると不便なので、ウィンドウの幅で折り返してくれたほうがありがたい。ただ、表の編集で問題が出る可能性はある。

アウトラインの操作

さて、前回書いたメモを保存したnotes.orgファイルを(Emacs以外のエディタで)覗いてみれば分かるが、.orgファイルというのは実のところ単なるテキストファイルで、*が見出しの印になっている。*の数が増えれば増えるほど階層が下になる。

* 大見出し

かくかくしかじか

** 中見出し1

あれやこれや

*** 小見出し1

うんぬんかんぬん

** 中見出し2

foo

*** 小見出し2

bar

上の例の場合、大見出しの下に中見出し、中見出しの下に小見出しがあり、各見出しの下に本文がある。階層に制限はなく、いくらでも*を増やすことができる。そして、*のある行でTABを押すと、その見出しよりも下の階層が折り畳まれて見えなくなる。折り畳まれていることは見出し末尾の...の有無でわかる。上位の見出し上でTABを何度か押すと折り畳み具合が変わる。言葉で書くとややこしいが、やってみればすぐ分かるだろう。

まっさらな状態でM-RET(RETはReturn/Enterキー)を打つと、*が挿入される。その時点で最上位の階層の見出しが入力できるようになるわけだ(もちろん、*の下であれば**が挿入される)。すでにある行を見出しにする(ようするに行頭に*を挿入)には、C-c *である。これはトグルになっているので、もう一度押すと元に戻る。別に、手でアスタリスクを書いたり消したりしてもいいのだが…。

行頭に一つでも*があれば、M-矢印キーで階層を動かすことができる。M-右矢印で階層が下に(*が一つ増える、例えば大見出しが中見出しになる)、M-左矢印で階層が上に(*が一つ減る)ということになる。また、SHIFTキーも押してM-S-矢印にすると、その見出し以下の階層すべてが動く。これも言葉で書くとピンとこないかもしれないが、やってみればすぐ分かる。

もう一つ重要なのが、サブツリー(見出しツリー)単位でのカット&ペーストだ。サブツリーというのは、ようするにある見出しからその下の階層すべて、ということだが、カットがC-c C-x C-w、ペーストがC-c C-x C-yである。上の例だと、中見出し1の上でC-c C-x C-wを叩くと、中見出し1と小見出し1がセットで切り取られる。これにより、見出しの組み換えや、後で出てくるメモの切り貼りが簡単にできるようになる。三連続の打鍵てなんだよ、覚えられねえよという向きもあるだろうが、多用するのですぐ覚えるだろう。

あとは、C-c C-nnextなので前進)とC-c C-p(previousなので後退)で見出しから見出しへジャンプできることを覚えておくとよい。段落から段落へはC-上矢印またはC-下矢印でジャンプできる。

他にも様々なキーバインドがあって、それはThe Org Manual: Structure editingを読めば分かるが、当面必要なのはこれくらいだと思う。

Org-refileの設定

前回説明したOrg-captureによるメモ取りをアウトライン・プロセッシングと組み合わせるには、Org-refileの設定をしておくと便利である。refileというのは、あるファイルの一部を、見出しツリー単位で他のファイルの見出しの下にリファイル(移動)するという機能で、これを使えばnotes.orgに記録したメモを簡単に他のファイルへ移すことができる。

最低限必要な~/.emacs.d/init.elの設定は

(setq org-agenda-files '("~/ownCloud/Org"))
(setq org-refile-targets '((org-agenda-files :maxlevel . 3)))

である。org-agenda-filesという変数名に変な感じがするかもしれないが、これは、後で説明するOrg-agendaという機能と共用しようと思っているからで、ようするにOrgディレクトリの中のファイルすべてを対象にする、ということだ。重要なのはその次のorg-refile-targetsで、Orgディレクトリ以下の.orgファイルに関し、maxlevelが3階層目、すなわち***の見出しまでを移動先として選べるようにするという指定である。

このように設定し、Orgディレクトリに.orgファイルを入れておけば、見出しの上でC-wを押すと、Refile subtree "指定した見出し" to (default 他のファイルの見出し(other.org)):みたいなメッセージがミニバッファに出ると思う。ここで他のファイルの中の見出しを指定してやれば、そこの下へ今C-wを叩いたサブツリーが一発で移動するのである。このように、Org-refileをうまく使うとファイル間で見出し項目の移動が素早くできるようになる。

ちなみに、すでにいじらないことがほぼ確定している.orgファイルがあると移動先として見えてしまってうざったいので、そういう場合はOrgディレクトリから消すか他へ移動するか、あるいはC-c $でアーカイヴ化するとよい。アーカイヴ化というと大層に聞こえるが、基本的には拡張子を.orgから.org_archiveに変えているだけである。

また、私自身は使っていないが、別に.orgファイルをOrgディレクトリ以下に置かなくても、org-refile-targets周りに少し手を加えて

; cf. https://www.emacswiki.org/emacs/OrgMode#toc21
(defun mhatta/org-buffer-files ()
  "Return list of opened Org mode buffer files"
  (mapcar (function buffer-file-name)
      (org-buffer-list 'files)))
(setq org-refile-targets
      (quote ((nil :maxlevel . 3)
          (mhatta/org-buffer-files :maxlevel . 1)
          (org-agenda-files :maxlevel . 3))))

などとすれば、現在バッファで開いている.orgファイルであれば、Orgディレクトリ下になくともリファイル先に指定できるようになる。

Org-refileについて更に細かく知りたい人は、The Org Manual: Refile and copyを読むと良いだろう。

具体的なワークフロー

以上のような設定をしておくと、次のようなワークフローで文章を書くことができるようになる。日本語のアウトライン・プロセッシングの解説書は、読んで見るとなんだかやたらややこしいというか、そういう機能があることは分かったが具体的にどう使ったらいいか分からないというか、しまいには人生訓みたいな話になって困惑することもあるのだが、これは比較的実用的だと思う。

  1. 原稿の.orgファイルをOrgディレクトリ以下に用意する。そうすればOrg-refileの対象になる。

  2. とりあえずM-RETを打って見出しを一つ用意し、文章のタイトルでも書く。* 文章のタイトルといった具合。一応文章全体が一つの見出しの下にあったほうが管理がしやすいと思う。実質的な見出しは**からということですね。

  3. 見出しのことなどはあまり考えず、とにかく思いつくことを、一行ずつ空けて単語や文章でがーっと列挙する。だらだらやっても限界があるので、5分とか時間を切ってやるとよい。

  4. あとは、C-c *等を使ってこれはというものを見出しにし、階層を変えたり順序を組み替えたりして、仮の目次というかアウトラインをでっちあげる。最初のアウトラインにこだわってもしょうがないというか、どうせ書いている最中に大きく変わるに決まっているので、あまり時間をかけるべきではない。3のアイデア出しも含めて、1ポモドーロ(25分)を超えると長すぎると思いますね。ちなみにこのブログ記事のアウトラインは、元は
    * アウトライン・プロセッサとしてのOrg mode
    
    ** キーバインド
    
    ** メモとの連携
    
    ** Org refile
    
    ** まとめ
    
    * 未整理
    

    みたいな感じだった。

    ポイントは、「未整理」という項目を用意することである。別に名前は「未整理」でなく、「メモ」でも「雑」でもなんでもよいのだが、本来の目次とは無関係な、一時バッファ的なものを末尾に置くわけです。notes.orgに保存したメモよりも上の階層の見出し(上の例では**ではなく*)が良い。

  5. あとは、書けるところから書く。途中で何か思いついたら、前回紹介したOrg-captureでメモをとる。文章を書いていると全然関係ないことを思いつくというか、むしろとりあえず書き始めないと何も思いつかないというところがあるので、とにかく書いてどんどんnotes.orgに保存していく。

  6. 行き詰まったらC-M-^でメモを呼び出して眺める。これは、というものがあったらOrg-refileで原稿の.orgファイルの「未整理」以下にリファイルする。

  7. 見出し「未整理」の内容を検討し、本文に移したり、見出しを組み替えたり、あるいはやっぱり無関係なので未整理から追い出してnotes.orgに戻したり、といった検討作業を行う。トップダウンででっちあげたアウトラインを、ボトムアップで集めたメモで補ったり変更したりして煮詰めていくわけだ。

  8. ある程度アウトラインが定まったら、本格的に書いて、まとめて、仕上げて終わり。もちろんこの段階で構成を組み替えたって一向に構わない。

こんな具合でOrg modeを、アウトライン・プロセッサとして活用してやれば、Org modeも以て瞑すべし、ということになるんじゃないでしょうかねえ。