ギッハブる日記

ギッハブで作る開発日誌

URLから本文を抜き出してblockquote作るプラグイン書いた

| Comments

URLから自動で本文らしい所を抜き取って引用文にしてくれるプラグイン書いた。

1
{% urlref https://github.com %}

こう書くと

GitHub - Social Coding

jQuery, reddit, Sparkle, curl, Ruby on Rails, node.js, ClickToFlash, Erlang/OTP, CakePHP, Redis, and many more

https://github.com

こんな感じ。楽チン。キャッシュ使って連続アクセスはしないようにした。

1
{% urlref http://twitter.com/hasegawayosuke/ %}

こんなのだと

Yosuke HASEGAWA (@hasegawayosuke)はTwitterを使っています

http://twitter.com/hasegawayosuke/

こんな感じだし

1
{% urlref https://twitter.com/hasegawayosuke/status/127346935911821312 %}

こんなのだと

Twitter / Yosuke HASEGAWA: 昨日に引き続き肉食べ過ぎて満腹。さぁ、大阪に帰ろう。

Twitter / Yosuke HASEGAWA: 昨日に引き続き肉食べ過ぎて満腹。さぁ、大阪に帰ろう。

https://twitter.com/hasegawayosuke/status/127346935911821312

焼肉食べたい。

Octopress

Octopress is a framework designed by Brandon Mathis for Jekyll, the blog aware static site generator powering Github Pages. To start blogging with Jekyll, you have to write your own HTML templates, CS…

http://octopress.org/

octopressにpull request送ったけど、取り入れられるかどうかは知らない。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#
# Author: Yasuhiro Matsumoto
# Include reference of text.
#
# Outputs a string with a given URL
#
#   {% urlref http://google.com/search?q=pants %}
#   ...
#   <blockquote>
#     <a href="http://google.com/search?q=pants">The Search For Bobby's Pants</p>
#     <p>...</p>
#     <cite><a href="http://google.com/search?q=pants">The Search For Bobby's Pants</a></cite>
#   </blockquote>
#
require 'cgi'
require 'digest/md5'
require 'net/https'
require 'uri'
require 'iconv'

module Jekyll

  class UrlRef < Liquid::Tag
    def initialize(tag_name, args, tokens)
      super
      if pair = args.match(/(\S+)\s+([\d\.]+)/)
        @url = pair[1].strip
        @per = pair[2].strip.to_f
      else
        @url = args
        @per = 0.1
      end
      @cache_disabled = false
      @cache_folder   = File.expand_path "../.urlref-cache", File.dirname(__FILE__)
      FileUtils.mkdir_p @cache_folder
    end

    def render(context)
      if text = get_cached_text(@url, @per) || get_text_from_url(@url, @per)
        lines = text.split(/\n/, 3)
        title = CGI.escapeHTML lines[1]
        body = CGI.escapeHTML lines[2]
        <<-HTML
<blockquote>
<a href="#{@url}">#{title}</a>
<p>#{body}</p>
<cite>#{@url}</cite>
</blockquote>
        HTML
      else
        ""
      end
    end

    def cache(url, text, per)
      cache_file = get_cache_file_for url, per
      File.open(cache_file, "w") do |io|
        io.write text
      end
    end

    def get_cached_text(url, per)
      return nil if @cache_disabled
      cache_file = get_cache_file_for url, per
      File.read cache_file if File.exist? cache_file
    end

    def get_cache_file_for(url, per)
      md5 = Digest::MD5.hexdigest url
      File.join @cache_folder, "#{md5}-#{per}.cache"
    end

    def decode_html(s)
      s = s.gsub(/<[^>]*?>/, "")
      s = s.gsub("&#39;", "'")
      s = s.gsub("&#39;", "'")
      s = s.gsub("&quot;", "\"")
      s = s.gsub("&lt;", "<")
      s = s.gsub("&gt;", ">")
      s = s.gsub("&nbsp;", " ")
      s = s.gsub("&laquo;", "<<")
      s = s.gsub("&raquo;", ">>")
      s = s.gsub("&copy;", "(C)")
      s = s.gsub("&amp;", "&")
      s
    end

    def get_text_from_url(url, threshold_per)
      raw_uri = URI.parse url
      proxy = ENV['http_proxy']
      if proxy
        proxy_uri = URI.parse proxy
        http = Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port).new raw_uri.host, raw_uri.port
      else
        http = Net::HTTP.new raw_uri.host, raw_uri.port
      end
      if raw_uri.scheme == 'https'
        http.use_ssl = true
        http.verify_mode = OpenSSL::SSL::VERIFY_NONE
      end
      request = Net::HTTP::Get.new raw_uri.request_uri
      data = http.request request
      data = data.body
      data.gsub!(/<!--.*?-->/, '')
      data.gsub!(/[\t\r\n]/, ' ')
      title = data.match(/<title[^>]*?>(.*?)<\/title>/i)
      title = title ? title[1] : ''
      title = decode_html title
      data.gsub!(/<(script|style)[^>]*>.*?<\/\1>/, '')
      max = 0
      body = ''
      data.split(/(<td[^>]*?>)|(<\/td>)|(<div[^>]*?>)|(<\/div>)/).each do |html|
        text = decode_html html.dup
        text.strip!
        text.gsub!(/[\s\t\r\n]+/, " ")
        next if text == ""
        l = text.length
        if l > 100
          per = l.to_f / html.length
          if max < l and per < threshold_per
            max = l
            body = text.strip
          end
        end
      end
      if body.length > 200
        body = "#{body.slice(0, 200)}..."
      end
      text = "#{url}\n#{title}\n#{body}\n"
      text = Iconv.new('UTF-8//IGNORE', 'UTF-8').iconv(text)
      cache url, text, threshold_per unless @cache_disabled
      text
    end

  end
end

Liquid::Template.register_tag('urlref', Jekyll::UrlRef)

Octopressのコードブロックでutf-8が使えないのが直った

| Comments

いままで

1
2
3
4
5
``` ruby
def foo 
  # 母さん元気ですか?僕は元気です
end
```

みたいなのがエラーで動かなかったんだけど、今日の修正で直ったみたい。

1
2
3
def foo?
  # 母さん元気ですか?僕は元気です
end

ただ、windowsだとpygmentsがちゃんと動かなくて、追ってみると

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
C:/Ruby192/lib/ruby/gems/1.9.1/gems/ffi-1.0.9-x86-mingw32/lib/ffi/library.rb:75:in `block in ffi_lib': Could not open library '.dll': 指定されたモジュールが見つ (LoadError)
        from C:/Ruby192/lib/ruby/gems/1.9.1/gems/ffi-1.0.9-x86-mingw32/lib/ffi/library.rb:54:in `map'
        from C:/Ruby192/lib/ruby/gems/1.9.1/gems/ffi-1.0.9-x86-mingw32/lib/ffi/library.rb:54:in `ffi_lib'
        from C:/Ruby192/lib/ruby/gems/1.9.1/gems/rubypython-0.5.1/lib/rubypython/python.rb:29:in `<module:Python>'
        from C:/Ruby192/lib/ruby/gems/1.9.1/gems/rubypython-0.5.1/lib/rubypython/python.rb:21:in `<top (required)>'
        from C:/Ruby192/lib/ruby/gems/1.9.1/gems/rubypython-0.5.1/lib/rubypython.rb:261:in `load'
        from C:/Ruby192/lib/ruby/gems/1.9.1/gems/rubypython-0.5.1/lib/rubypython.rb:261:in `reload_library'
        from C:/Ruby192/lib/ruby/gems/1.9.1/gems/rubypython-0.5.1/lib/rubypython.rb:104:in `start'
        from C:/Ruby192/lib/ruby/gems/1.9.1/gems/pygments.rb-0.1.3/lib/pygments/ffi.rb:8:in `start'
        from C:/Ruby192/lib/ruby/gems/1.9.1/gems/pygments.rb-0.1.3/lib/pygments/ffi.rb:82:in `highlight'
        from C:/temp/github/octopress/plugins/pygments_code.rb:24:in `pygments'        from C:/temp/github/octopress/plugins/pygments_code.rb:14:in `highlight'
        from C:/temp/github/octopress/plugins/backtick_code_block.rb:37:in `block in render_code_block'
        from C:/temp/github/octopress/plugins/backtick_code_block.rb:13:in `gsub'
        from C:/temp/github/octopress/plugins/backtick_code_block.rb:13:in `render_code_block'
        from C:/temp/github/octopress/plugins/octopress_filters.rb:12:in `pre_filter'
        from C:/temp/github/octopress/plugins/octopress_filters.rb:27:in `pre_render'
        from C:/temp/github/octopress/plugins/post_filters.rb:112:in `block in pre_render'
        from C:/temp/github/octopress/plugins/post_filters.rb:111:in `each'
        from C:/temp/github/octopress/plugins/post_filters.rb:111:in `pre_render'
        from C:/temp/github/octopress/plugins/post_filters.rb:166:in `do_layout'
        from C:/Ruby192/lib/ruby/gems/1.9.1/gems/jekyll-0.11.0/lib/jekyll/post.rb:189:in `render'
        from C:/Ruby192/lib/ruby/gems/1.9.1/gems/jekyll-0.11.0/lib/jekyll/site.rb:193:in `block in render'
        from C:/Ruby192/lib/ruby/gems/1.9.1/gems/jekyll-0.11.0/lib/jekyll/site.rb:192:in `each'
        from C:/Ruby192/lib/ruby/gems/1.9.1/gems/jekyll-0.11.0/lib/jekyll/site.rb:192:in `render'
        from C:/Ruby192/lib/ruby/gems/1.9.1/gems/jekyll-0.11.0/lib/jekyll/site.rb:40:in `process'
        from C:/Ruby192/lib/ruby/gems/1.9.1/gems/jekyll-0.11.0/bin/jekyll:250:in `<top (required)>'
        from C:/Ruby192/bin/jekyll:19:in `load'
        from C:/Ruby192/bin/jekyll:19:in `<main>'

どうやらpygmentsが使うpythonのdllが見つからないっぽい。でrubypythonを見てみると、ちゃんとpython27.dllのパスを探せてない。パッチ書こうと思ったら既にあった

Liquid error: undefined method `map’ for #<String:0x21f8c58>

早く取り込んでよ。8月のだよ。で動かしてみたけど読み込めない。調べたら、python27.dllはc:\python27\libs\python27.dllでもc:\python27\python27.dllでもなく、c:\windows\system32\python27.dllなんて所に入ってた。f*ckインストーラ! こういうのは動かすと必ず問題が起きるのでc:\python27\libs\python27.dllにコピーした。 ようやくちゃんと動いた。

快適。

「githubとjekyllとoctopressで作る簡単でモダンなブログ」をmarkdownで書き直してみた

| Comments

自分で書いた記事だけど…

Liquid error: undefined method `map’ for #<String:0x2218ba8>

を実際にoctopressで書くと、どんな感じかやってみた。 まぁblosxomのテキストをmarkdownに書き直しただけなんですが。 一番下に、markdownにした場合のテキストを貼り付けてあります。


以前、「jekyllで始める簡単ブログ」という記事を書いたのですが

Liquid error: undefined method `map’ for #<String:0x2218878>

octopressというのを使うともっと簡単に出来る事が分かった。

Liquid error: undefined method `map’ for #<String:0x2218590>

Liquid error: undefined method `map’ for #<String:0x2218260>

以下簡単な手順を示す。 このgithubリポジトリは基本的に、1ブログに対して1つcloneする。cloneしたら

1
# rake install

する。octopressをシステムにインストールのではなく、このブログ用リポジトリにsassテーマをキャッシュさせる為の設定を行うだけなので安心してやって貰ってok。 次にgithubにブログを作るのであれば

1
# rake setup_github_pages

を実行し、読み取り書き込み権限のあるgit URLを貼り付けて完了。 Windowsの場合はちょっとここで修正が必要で、config.rbとかRakefileに変なパスが書かれているので直す。実際にはpublic/c:/path/to/public...みたいなフルパスが重なっているはずなのでpublic...に直せばok。 これについては時間があったらパッチ書いてpull requestを送るつもり。

さて、これでブログを書く準備が出来ました。簡単すぎますね!

試しにsource/_posts/2011-10-17-github-jekyll.mkdというmarkdownのファイルを作ります。中身は以前ご紹介した内容と変わりませんが、ocotopressは幾らか拡張プラグインが入っているので色んな書き方が出来ます。 例えばgist tagプラグインを使って

1
2
3
4
5
6
7
8
9
10
---
layout: post
title: "githubとjekyllとoctopressで作るブログ"
date: 2011-07-03 5:59
comments: true
categories:
---
便利すぎる...

{% gist 1292428 %}

こう書いて

1
# rake gen_deploy

すると

こんな記事が出来上がります。dateはファイル名じゃなくてdateの方が(設定されていれば)優先されるみたいですね。以後は記事を書いてrake den_deployするだけの簡単なお仕事です。 他にも、imageタグや、haml形式入力、html5 videoタグなど、色んなプラグインがあります。また、sassフォルダ内にあるsassファイルを弄れば簡単しかも柔軟なCSSを吐き出せます。 なお、_config.xmlを弄ってタイトルやサブタイトル、githubアカウント、twitterアカウントなんかを設定すると上述の様なサイトが簡単に出来上がります。

1
2
3
4
5
6
7
8
# ----------------------- #
#      Main Configs       #
# ----------------------- #

url: http://mattn.github.com/blog
title: "ギッハブる日記"
subtitle: ギッハブで作る開発日誌
author: mattn

気をつけておいて欲しいのは、github/jekyllはCGIで動いている訳じゃなくて、octopressが静的コンテンツを生成しているので、記事をアップする環境に依存する事。まぁここはbundleを使っているのでOSさえ変わらなければ大丈夫かと思います。Windowsからでも既述の様な修正を入れれば使えています。無料のgithubで簡単にしかもモダンなブログサイトを作りたい方は、一考してみてはどうでしょうか。


以上が本文、でこのmarkdownのソースは以下。

しかしgist tagプラグイン便利だ。