意識の高いLISPマシン

藤原惟/すかいゆき(@sky_y)の技術用ブログ

simple-hatena-modeで書いてみた

SimpleHatenaMode – CodeRepos::Share – Trac

このパッケージは、「はてなダイアリーライター」をEmacsから使えるようにし、はてなダイアリー/グループ日記を簡単に更新するためのメジャーモード、simple-hatena-modeを提供します。

ついでに hatenahelper-mode も適用。
はてな記法を入力支援する hatenahelper-mode - おもてなしの空間


導入が面倒でずっと入れてなかったのですが、ようやく重い腰を上げて導入してみました。
テスト記事としてこの記事を書いてみたので、これが表示されてたら成功。
Emacsから直接はてダ書けるのは嬉しいです。

Emacs 24.2 on Mac OS X のインストール

Emacs24.2の正式版がリリースされたということで、インストールしてみました。


基本的なやり方は以下のサイトを読めばOKです。
ただし、IMEパッチの適用 という項に従ってください。
(これ以外の方法だと、日本語の入力で不具合が起こります。)


Emacs24 のインストールと新機能

インストールの注意点

  • 設定ファイルは ~/.emacs や ~/.emacs.el ではなく、~/.emacs.d/init.el を使用しましょう。
    • Emacs24のパッケージシステムは .emacs.d/elpa にインストールするので、~/.emacs.dディレクトリは必ず作りましょう。
  • IMEパッチで最新版のautoconfが必要になります。備え付けのautoconfは古いので、HomebrewやMacportsなどで最新版をインストールしてください。
  • 一部のelispが読み込み時にエラーになることがあります(というかたぶんなります。)その際は、以下のようにバージョンごとに場合分けされるように一旦しましょう。
	;; Emacs24以降で有効にしたい
	(when (>= emacs-major-version 24)
	  (hoge)) 


	;; Emacs23以前で有効にしたい
	(when (<= emacs-major-version 23)	  
	  (fuga))
  • elispのエラーは --debug-init を使いながら地道に解消していきます。
	cd path/to/emacs-24.2
	./nextstep/Emacs.app/Contents/MacOS/Emacs --debug-init &

Elscreenのインストールと注意点


私は以前からElscreenを使っていましたが、Emacs24にアップデートして、
Elscreenが動かなくて困りました。


少し調べてみると、Emacs24のpackageに入っているElscreenは
[GitHub: shosti/elscreen](https://github.com/shosti/elscreen)
のもので、従来のものとはだいぶ異なるようです。

  • Emacs24のElscreenは、従来のソースをforkしたもの
  • APEL非依存な形に書き換えられている(ので、インストールが楽!)
  • init.elに (elscreen-start) と書けば使える
  • その他の設定・変数はほぼ従来通り


というわけで、packageシステムからElscreenをインストールします。

  1. M-x list-packages
  2. Elscreenを選んでインストール
  3. init.elを以下のように書き換える
	;; APEL非依存版 (Emacs 24の場合)
	(when (>= emacs-major-version 24)
	  (elscreen-start))


	;; APEL依存版 (Emacs 23と同居させたい場合)
	(when (<= emacs-major-version 23)
	  (add-to-load-path "elisp/apel")
	  (require 'elscreen))


	;; 以下、従来通りの設定

(ツール紹介)Markdown記法をはてな記法に変換するツール

最近、ちょっとした文書をMarkdownでドキュメントを書くことが多いです。
しかし、このブログ(技術的な話専用)がはてなダイアリーなので、
うっかりドキュメントをMarkdownで書いてしまうと、はてな記法への書き換えが若干面倒でした。


ググったところ、はてな記法に変換するツールをMarkdownに変換してくれるツールを見つけましたが、
コンパイル方法について記述が無かったので、ここで補足しておきます。

markdown2hatena (joker1007 さん作)

Haskellを使ってmarkdownをパースしてはてな記法に変換する

続・Haskellを使ってmarkdownをパースしてはてな記法に変換する

というわけで、現在対応しているのは以下の記法。


頭に#をつけるタイプの見出し記法。見出しレベル対応。
順序無しリスト(スペース4つ、もしくはタブ1つで1レベルインデント)
順序付きリスト(スペース4つ、もしくはタブ1つで1レベルインデント)
ノーマルなパラグラフ
見出し、リスト、パラグラフ中に存在するリンク記法

今後のToDo


コードブロック対応
引用ブロック対応
画像貼りつけ対応

今後に期待です。

ソースコード

joker1007/markdown2hatena · GitHub


Haskellソースコードしかないので、自分でコンパイルする必要があります。

コンパイル方法

必要なもの
  • Haskellコンパイラ GHC
    • Haskell Platformというパッケージでインストールすることをおすすめします。一緒にパッケージマネージャなんかもインストールしてくれます。
  • Git
  • お好みで、Haskellに対応したエディタ
手順

1. 端末上で適当なディレクトリに移り、上記GitHubサイトからgit cloneします。

$ git clone https://github.com/joker1007/markdown2hatena.git

2. markdown2hatenaディレクトリに移ります:

$ cd markdown2hatena 

3. エディタでmain.hsを開き、一番上の import System をコメントアウトして

-- import System

に変えます。

  • 新しいGHCコンパイラではimportする必要ないらしく、付けるとエラーになります。

4.

$ ghc -o markdown2hatena main.hs

とすると、コンパイルして"markdown2hatena"という実行ファイルを吐き出してくれます(実行ファイルの名前はお好みで)。
5. 下記の「使い方」を試してOKだったら、PATHの通っているディレクトリに実行ファイルを置いて完了。

使い方

Markdown形式のファイルを標準入力に流し込みます。

$ ./markdown2hatena < sample.markdown
*見出し1


パラグラフ1
パラグラフ1
パラグラフ1


パラグラフ2
パラグラフ2
パラグラフ2


パラグラフ3
-Red
-Green
--Green
-Blue
--Blue
---Blue
パラグラフ3


**見出し2
パラグラフ1
  ## パラグラフ1


+White
+Silver
++Black
+White


"ダブルクォート"
テキスト[http://www.google.com/:title=リンク] テキスト
[http://www.yahoo.com/:title=リンク]


***[http://www.google.com/:title=リンク]
-[http://www.yahoo.com/:title=リンク]
-[http://www.yahoo.com/:title=リンク]
-[http://www.yahoo.com/:title=リンク]

ファイルに書き込む場合は下記の通りにします(はてな記法の拡張子は適当)。

$ ./markdown2hatena < sample.markdown > sample.hatena

便利な使い方

似たようなツールでPandocというのがあります。


Pandoc can convert documents in markdown, reStructuredText, textile, HTML, DocBook, or LaTeX to


HTML formats: XHTML, HTML5, and HTML slide shows using Slidy, Slideous, S5, or DZSlides.
Word processor formats: Microsoft Word docx, OpenOffice/LibreOffice ODT, OpenDocument XML
Ebooks: EPUB
Documentation formats: DocBook, GNU TexInfo, Groff man pages
TeX formats: LaTeX, ConTeXt, LaTeX Beamer slides
PDF via LaTeX
Lightweight markup formats: Markdown, reStructuredText, AsciiDoc, MediaWiki markup, Emacs Org-Mode, Textile


これと上述のmarkdown2hatenaを組み合わせると、色々な記法をはてな記法に変換出来ます(詳細は省きますが、リダイレクションを使うと綺麗に書けると思います)。

Ruby: コマンドライン引数の解析で使うoptparseをもっと柔軟に

オプションの無い引数を扱いたい

Rubyコマンドライン引数を解析するときは、optparse (OptionParser) を使うと便利です。

library optparse


しかし、OptionParser#parse! は、"-a", "--long-option"みたいなオプションを使わない引数を扱う場合に不便です。

つまり、コマンドライン

$ ruby foo.rb -o file_output.txt file_input.html 

みたいなことをしようと思うと、RubyでOptionParserを使う前に

# ruby
opt = OptionParser.new
@option[:file] = ARGV.pop
# ...
opt.on('-o FILE','--output FILE','Output Filename') {|v| @option[:file_output] = v }
# ...
opt.parse!(ARGV)

みたいに、ARGV.popで引数を取り出す必要があります。


この場合、オプションの無い引数が必ず末尾に来ないといけないので、
かなり窮屈なコマンドインタフェースになります。

オプション無しの引数をもっと柔軟に扱う

それを解決する方法は、OptionParser#parse! を使うのではなく、OptionParser#permute! を使うことです。

instance method OptionParser#permute!

permute!(argv = self.default_argv) -> [String]
与えられた argv を破壊的にパースします。argv からオプションがすべて取り除かれます オプションではないコマンドの引数(下の例で言うと somefile)があってもパースを中断しません。 argv を返します。

下の例で言うと、order と違いコマンドの引数 somefile よりも後ろにオプションを置くことが できます。

例:

$ cat opt.rb
require 'optparse'
opt = OptionParser.new

opt.on('-a [VAL]') {|v| p :a }
opt.on('-b ') {|v| p :b }

opt.permute!(ARGV)
p ARGV

$ ruby opt2.rb -a foo somefile -b
:a
:b
["somefile"]


これを使うと、パース(permute)後のARGVにオプション無し引数が残ってくれるので、
ARGV.popでオプション無し引数を簡単に取り出せます。
(順番さえ守れば)オプション無し引数の位置も好きな位置に置けます。


例えば、以下のように、オプション付き引数(-o file_output.txt)の前に
オプション無しの引数(file_input.html)を与えることもできます。

$ ruby foo.rb file_input.html -o file_output.txt  

Emacs小ネタ: MacでPDFからコピーすると濁点が分離する問題を直す

Macでは、PDFからコピーすると濁点が分離する問題があります。

参考: PDFからコピーした濁点/半濁点付きの文字列をFirefoxに貼り付けた時におかしくなる問題の対処方法 - 強火で進め

それをEmacs上で直すelispを書いてみました。

;; ucs-normalize-NFC-region で濁点分離を直す
;; M-x ucs-normalize-NFC-buffer または "C-x RET u" で、
;; バッファ全体の濁点分離を直します。
;; 参考:
;; http://d.hatena.ne.jp/nakamura001/20120529/1338305696 
;; http://www.sakito.com/2010/05/mac-os-x-normalization.html

(require 'ucs-normalize)
(prefer-coding-system 'utf-8-hfs)
(setq file-name-coding-system 'utf-8-hfs)
(setq locale-coding-system 'utf-8-hfs)

(defun ucs-normalize-NFC-buffer ()
  (interactive)
  (ucs-normalize-NFC-region (point-min) (point-max))
  )

(global-set-key (kbd "C-x RET u") 'ucs-normalize-NFC-buffer)

また、例のごとくgistに上げています。よければお使いください。

Emacs: MacでPDFからコピーすると濁点が分離する問題を直す

追記

(require 'ucs-normalize) しておくと、ucs-normalize-NFC-regionという関数が使えます。

濁点分離を直したい部分をリージョン選択して、「M-x ucs-normalize-NFC-region」でその部分だけ直ります。

Emacs小ネタ: ファイル名の上にポインタ動かしてC-c oするとファイル開いたりdiredに飛べるようにする

Emacselispいじっているときに

  • "hoge.el" みたいなファイルを同じEmacsで開いたり
  • "~/Dropbox/fuga" みたいなディレクトリをdiredで開いたり

したいときってありますよね。

そういうときのために、設定を書いてみました。
(参考:Emacs, Mac OS X and Unix: EmacsのバッファやDiredでカーソル位置のファイル(URL)をFinder(ウェブブラウザ)で開く

;; Open the file name being pointed in an other window or dired
;; reference: http://kouzuka.blogspot.com/2011/02/emacsurlfinder.html
(defun my-directory-or-file-p (path)
  "return t if path is a directory,
return nil if path is a file"
  (car (file-attributes path)))

(defun my-open-emacs-at-point ()
  "open the file with opening emacs"
  (interactive)
  (require 'ffap)
  (let ((file (or (ffap-url-at-point)
                  (ffap-file-at-point))))
    (unless (stringp file)
      (error"No file or URL found"))
    (when (file-exists-p (expand-file-name file))
      (setq file (expand-file-name file)))
    (message "Open: %s" file)

    (if (my-directory-or-file-p file)
      (dired-other-window file)
      (find-file-other-window file))
    
    ))

(global-set-key (kbd "\C-c o") 'my-open-emacs-at-point)

;; double click
(global-set-key [double-mouse-1] 'my-open-emacs-at-point)
(global-set-key [double-down-mouse-1] 'ignore) ; mouse-drag-region

長いので、gistにも載せておきます。

Emacs: Open the file which filename is pointed in an other window or dired

補足

my-directory-or-file-p 関数は、ディレクトリだったらtを、ファイルだったらnilを返します。

(単純に file-attributes 関数の返すリストの要素1個目を返しているだけですが。)

Emacs小ネタ:M-f (forward-word) の挙動を改良する

僕はM-fを forward-word に、M-bをbackward-word に当ててました。
つまり、単語単位で移動してほしいのです。

しかし、M-fすると単語の前のスペースに移動してしまいます。
僕はその先の単語頭に移動してほしいので、若干イライラしていました。

というわけでググってみたら、改良策があったので掲載します。
わずかの改良で幸せになれるので、お試しを。

;; M-f,M-b for backward/forward word exactly
(require 'misc)
(global-set-key "\M-f" 'forward-to-word)
(global-set-key "\M-b" 'backward-to-word)