プログラマ 福重 伸太朗 〜基本へ帰ろう〜 このページをアンテナに追加 RSSフィード

2007-11-28

テキストに含まれる http://〜〜を ハイパーリンクするように変換

●何がしたいのか

たとえば、

必読! http://gettingreal.37signals.com/GR_jpn.php ど う ぞ

というテキストを

必読! <a herf="http://gettingreal.37signals.com/GR_jpn.php">http://gettingreal.37signals.com/GR_jpn.php</a> ど う ぞ

というように、aタグをつけて変換したい。


●作ってみた

・hyperlink_for_url.rb

=begin
Example:
    require 'hyperlink_for_url'
    
    str = "必読! http://gettingreal.37signals.com/GR_jpn.php ど う ぞ"
    converted =  HyperlinkForUrl::Conversion.conversion(str)

Note:
    It made it on November 28, 2007
    It made it with Ruby 1.8.6
    The character-code is utf8
    It corresponds to http: and https:
=end

module HyperlinkForUrl
  class Conversion
    def self.number_of_checks_of_http(str)
      str << "\n"
      i = count = 0
      check = ""
      @delimitation = []
      str.each_byte {|c|
        if check == "http:" || check == "https:"
          @delimitation[i] = count-5 if check == "http:"
          @delimitation[i] = count-6 if check == "https:"
          i = i + 1
          check = ""
        end
      
        if check == "http" || check == "https"
          check << ":" if c == 58   # 58=>:
          check << ":" if c == 115  # 115=>s
        end
       
        if check == "htt"
          check << "p" if c == 112  # 112=>p
        end

        if check == "ht"
          check << "t" if c == 116  # 116=>t
        end
        
        if check == "h"
          check = check + "t" if c == 116  # 116=>t
        end
        
        check = "h" if c == 104  # 104=>h
        
      count = count + 1
      }
      @delimitation
    end

    def self.hyperlink_for_url(str,url)
      cutting_url = []
      y   = 0
      url.each do |@delimitation_start|
      
      #(httpから数えて、最初の「半角空白」もしくは「改行」の場所を取得)
        i = count =0
        @delimitation = []
        str.each_byte {|c|
          if 32 == c  # 32=>SP
            @delimitation[i] = count
            i = i + 1
          end

          if 10 == c  # 10=>\n
            @delimitation[i] = count
            i = i + 1
          end

          if 13 == c  # 13=>\r
            @delimitation[i] = count
            i = i + 1
          end
        count = count + 1
        }

        #(配列のなかから、@delimitation_startより数字が大きい中で、一番数が小さいものを探す。)
        @delimitation.delete_if {|x| x <= @delimitation_start}
        
        #配列が空だったら count を代入
        if @delimitation == []
          @delimitation[0] = count
        end

        #(URL切り出し)
        cutting_url[y] = str[@delimitation_start..@delimitation[0]-1]
        y = y + 1
      end

      n = 0
      record = []
      cutting_url.each do |u|
        #aタグを使ってハイパーリンクにする
        if record == []
            #str = str.gsub(/#{u}\s|#{u}\r|#{u}\r\n|#{u}\n/, "<a href='#{u}'>#{u}</a>")
            str = str.gsub("#{u}", "<a href='#{u}'>#{u}</a>")
            record[n] = u
            n = n + 1
        else
          record.each do |r|
            @check = false
            if r != u
              @check = true
            end
          end
          
          if @check
            #str = str.gsub(/#{u}\s|#{u}\r|#{u}\r\n|#{u}\n/, "<a href='#{u}'>#{u}</a>")
            str = str.gsub("#{u}", "<a href='#{u}'>#{u}</a>")
            record[n] = u
            n = n + 1
          end
        end
      end
      str
    end

    def self.conversion(str)
      address = self.number_of_checks_of_http(str)
      str = self.hyperlink_for_url(str,address)
      str = str.chomp
      str
    end
  end
end

●テスト

・test_hyperlink_for_url.rb

require 'test/unit'
require 'hyperlink_for_url'

class ConversionTest < Test::Unit::TestCase

  def setup
  end

  def test_when_the_url_back_is_a_blank
    str = "must read! http://gettingreal.37signals.com/GR_jpn.php please"
    str = HyperlinkForUrl::Conversion.conversion(str)
    assert_equal str, "must read! <a href='http://gettingreal.37signals.com/GR_jpn.php'>http://gettingreal.37signals.com/GR_jpn.php</a> please"
  end

  def test_when_the_url_back_is_a_n
    str = "must read! http://gettingreal.37signals.com/GR_jpn.php\nplease"
    str = HyperlinkForUrl::Conversion.conversion(str)
    assert_equal str, "must read! <a href='http://gettingreal.37signals.com/GR_jpn.php'>http://gettingreal.37signals.com/GR_jpn.php</a>\nplease"
  end

  def test_when_the_url_back_is_a_r
    str = "must read! http://gettingreal.37signals.com/GR_jpn.php\rplease"
    str = HyperlinkForUrl::Conversion.conversion(str)
    assert_equal str, "must read! <a href='http://gettingreal.37signals.com/GR_jpn.php'>http://gettingreal.37signals.com/GR_jpn.php</a>\rplease"
  end

  def test_when_the_url_back_is_a_n_r
    str = "must read! http://gettingreal.37signals.com/GR_jpn.php\r\nplease"
    str = HyperlinkForUrl::Conversion.conversion(str)
    assert_equal str, "must read! <a href='http://gettingreal.37signals.com/GR_jpn.php'>http://gettingreal.37signals.com/GR_jpn.php</a>\r\nplease"
  end

  def test_when_the_url_back_is_none
    str = "must read! http://gettingreal.37signals.com/GR_jpn.php"
    str = HyperlinkForUrl::Conversion.conversion(str)
    assert_equal str, "must read! <a href='http://gettingreal.37signals.com/GR_jpn.php'>http://gettingreal.37signals.com/GR_jpn.php</a>"
  end

  def test_for_two_or_more_lines
    str = "must read! http://gettingreal.37signals.com/GR_jpn.php\r\nyes http://google.com/ \r\n and https://google.com/"
    count = 0
    s = []
    str.each_line {|line| 
      s[count] = HyperlinkForUrl::Conversion.conversion(line)
      count = count + 1
    }
    assert_equal s[0], "must read! <a href='http://gettingreal.37signals.com/GR_jpn.php'>http://gettingreal.37signals.com/GR_jpn.php</a>\r\n"
    assert_equal s[1], "yes <a href='http://google.com/'>http://google.com/</a> \r\n"
    assert_equal s[2], " and <a href='https://google.com/'>https://google.com/</a>"
  end

  def test_when_there_are_two_or_more_url_in_one_line
    str = "must read! http://gettingreal.37signals.com/GR_jpn.php http://google.com/"
    str = HyperlinkForUrl::Conversion.conversion(str)
    assert_equal str, "must read! <a href='http://gettingreal.37signals.com/GR_jpn.php'>http://gettingreal.37signals.com/GR_jpn.php</a> <a href='http://google.com/'>http://google.com/</a>"
  end

  def test_when_same_url_exists
    str = "must read! http://google.com/ http://google.com/"
    str = HyperlinkForUrl::Conversion.conversion(str)
    assert_equal str, "must read! <a href='http://google.com/'>http://google.com/</a> <a href='http://google.com/'>http://google.com/</a>"
  end

  def test_when_same_url_is_in_another_line
    str = "must read! http://google.com/ http://google.com/\r\n http://google.com/"
    str = HyperlinkForUrl::Conversion.conversion(str)
    assert_equal str, "must read! <a href='http://google.com/'>http://google.com/</a> <a href='http://google.com/'>http://google.com/</a>\r\n <a href='http://google.com/'>http://google.com/</a>"
  end

  def test_when_same_url_is_in_another_line_2
    str = "aa http://google.com/ aa \r\naa http://yahoo.co.jp/ \r\n http://google.com/ http://live-revolution.co.jp a"

    count = 0
    s = []
    str.each_line {|line| 
      s[count] = HyperlinkForUrl::Conversion.conversion(line)
      count = count + 1
    }
    assert_equal s[0], "aa <a href='http://google.com/'>http://google.com/</a> aa \r\n"
    assert_equal s[1], "aa <a href='http://yahoo.co.jp/'>http://yahoo.co.jp/</a> \r\n"
    assert_equal s[2], " <a href='http://google.com/'>http://google.com/</a> <a href='http://live-revolution.co.jp'>http://live-revolution.co.jp</a> a"
  end

  def test_when_there_is_https
    str = "https://google.com/"
    str = HyperlinkForUrl::Conversion.conversion(str)
    assert_equal str, "<a href='https://google.com/'>https://google.com/</a>"
  end

  def test_when_http_exists_together_to_https
    str = "https://google.com/ http://google.com/"
    str = HyperlinkForUrl::Conversion.conversion(str)
    assert_equal str, "<a href='https://google.com/'>https://google.com/</a> <a href='http://google.com/'>http://google.com/</a>"
  end

  def test_when_there_is_question_mark
    str = "http://google.com/?test=test"
    str = HyperlinkForUrl::Conversion.conversion(str)
    assert_equal str, "<a href='http://google.com/?test=test'>http://google.com/?test=test</a>"
  end
end

●使い方

require 'hyperlink_for_url'

str = "必読! http://gettingreal.37signals.com/GR_jpn.php ど う ぞ"
converted =  HyperlinkForUrl::Conversion.conversion(str)
p converted  #=> 必読! <a herf="http://gettingreal.37signals.com/GR_jpn.php">http://gettingreal.37signals.com/GR_jpn.php</a> ど う ぞ

2007-11-12

CentOS4.5にRMagickをインストール

no title

↑コチラ様を参考にやってみる。

ImageMagickインストールされているか確認

# rpm -qa |grep ImageMagick
ImageMagick-6.2.8.0-3.el5.4

入っているっぽい。

Rubyインストールされているか確認

# ruby -v
ruby 1.8.6 (2007-03-13 patchlevel 0) [i686-linux]

ちゃんと入ってる。

○「gem install RMagick」をやる。

# gem install RMagick
Bulk updating Gem source index for: http://gems.rubyforge.org
Building native extensions.  This could take a while...
ERROR:  While executing gem ... (Gem::Installer::ExtensionBuildError)
    ERROR: Failed to build gem native extension.

ruby gem_extconf.rb install RMagick

sh configure 

Configuring RMagick 1.13.0
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables... 
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for gcc option to accept ISO C99... -std=gnu99
checking for gcc -std=gnu99 option to accept ISO Standard C... (cached) -std=gnu99
checking for ruby... /usr/bin/ruby
checking for Magick-config... no
checking for GraphicsMagick-config... no
configure: error: Can't install RMagick. Can't find Magick-config or GraphicsMagick-config program.
RMagick configuration failed with status 1.


Gem files will remain installed in /usr/lib/ruby/gems/1.8/gems/rmagick-1.15.10 for inspection.
Results logged to /usr/lib/ruby/gems/1.8/gems/rmagick-1.15.10/gem_make.out

むむ。「Can't install RMagick. Can't find Magick-config or GraphicsMagick-config program.」と言われておる。

ということで、yum install ImageMagick-devel をやる。

yum install ImageMagick-devel

ローカルで使っているRMagickのバージョンが1.13.0なので同じものを入れる。

# gem install RMagick -v 1.13.0
Need to update 1 gems from http://gems.rubyforge.org
.
complete
Building native extensions.  This could take a while...
ERROR:  While executing gem ... (Gem::Installer::ExtensionBuildError)
    ERROR: Failed to build gem native extension.

ruby gem_extconf.rb install RMagick -v 1.13.0

sh configure 

〜長いので省略〜

/usr/lib/ruby/gems/1.8/gems/rmagick-1.13.0/./lib/rvg/misc.rb:317:in `get_type_metrics': unable to read font `/usr/share/fonts/default/TrueType/verdana.ttf' (Magick::ImageMagickError)
〜長いので省略〜
Gem files will remain installed in /usr/lib/ruby/gems/1.8/gems/rmagick-1.13.0 for inspection.
Results logged to /usr/lib/ruby/gems/1.8/gems/rmagick-1.13.0/gem_make.out

「/usr/lib/ruby/gems/1.8/gems/rmagick-1.13.0/./lib/rvg/misc.rb:317:in `get_type_metrics': unable to read font `/usr/share/fonts/default/TrueType/verdana.ttf' (Magick::ImageMagickError)」

↑これが怪しい。

verdana.ttfはフォントだが、これがないと怒っている。

じゃぁということで、Windows(「C:\WINDOWS\Fonts」)からコピーして持って行ってみる。

また「/usr/share/fonts/default/TrueType/」というディレクトリがなかったので作成した。

mkdir /usr/share/fonts/default/TrueType/

そして「C:\WINDOWS\Fonts\verdana.ttf」を「/usr/share/fonts/default/TrueType/」にアップ。

で、再度チャレンジ。

こんどは、

/usr/lib/ruby/gems/1.8/gems/rmagick-1.13.0/./lib/rvg/misc.rb:317:in `get_type_metrics': unable to read font `/usr/share/fonts/default/TrueType/arialbd.ttf' (Magick::ImageMagickError)

と言われる。

同じように、「C:\WINDOWS\Fonts\arialbd.ttf」からコピー。

で、再度チャレンジ。

こんどは、

/usr/lib/ruby/gems/1.8/gems/rmagick-1.13.0/./lib/rvg/misc.rb:317:in `get_type_metrics': unable to read font `/usr/share/fonts/default/TrueType/arialbi.ttf' (Magick::ImageMagickError)

と言われる。

同じように、「C:\WINDOWS\Fonts\arialbi.ttf」からコピー。

で、再度チャレンジ。

こんどは、

/usr/lib/ruby/gems/1.8/gems/rmagick-1.13.0/./lib/rvg/misc.rb:317:in `get_type_metrics': unable to read font `/usr/share/fonts/default/TrueType/arial.ttf' (Magick::ImageMagickError)

と言われる・・・っていつまで続くの・・・。

同じように、「C:\WINDOWS\Fonts\arial.ttf」からコピー。

で、再度チャレンジ。

[root@localhost opt]# gem install RMagick -v 1.13.0
Building native extensions.  This could take a while...

Successfully installed rmagick-1.13.0

おおおぉ!成功!

RMagickで画像をリサイズ - プログラマ 福重 伸太朗 〜基本へ帰ろう〜

↑のプログラムを実行したら、ちゃんと動きました。



※こんなエラーの場合。

RMagick: Postscript delegate failed `/tmp/magick-XXcXbhNb'.
/usr/lib/ruby/gems/1.8/gems/rmagick-1.13.0/./lib/rvg/misc.rb:317:in `get_type_metrics': Can't measure text. Are the fonts installed? Is the FreeType library installed? (RuntimeError)
yum install ghostscript*

↑こんな感じで解決。

2007-11-10

RMagickで画像をリサイズ

まずは、ImageMagickとRMagickがインストールされていないといけませんので、インストールRailsで画像をアップしてみよう!(FileColumn,RMagick,ImageMagick) for windows XP - プログラマ 福重 伸太朗 〜基本へ帰ろう〜などを参考にしてください。

あ、もちろんRubyのインストールも必要です。

ImageMagickとRMagickのインストール例:

○Windows
・ImageMagick RMagick ダウンロード
http://rubyforge.org/frs/download.php/12421/rmagick-1.13.0-IM-6.2.9-0-win32.zip
・ImageMagickインストール(すべてデフォルト)
ImageMagickインストール(ImageMagick-6.2.9-0-Q8-windows-dll.exeをダブルクリック
・RMagickインストール(展開したファイルのカレントディレクトリで)
>gem install rmagick-1.13.0-win32.gem

Linux(CentOS4.5)

参考⇒CentOS4.5にRMagickをインストール - プログラマ 福重 伸太朗 〜基本へ帰ろう〜


インストールされていれば簡単!

まずは、test.jpg というイメージファイルを用意します。

そして、以下のrubyコードと同じ階層に置きます。

・resize.rb

require 'rubygems'
require 'RMagick'

image = "test.jpg"
original = Magick::Image.read(image).first
resized = original.resize_to_fit(75,100)
resized.write("test_resized.jpg")

それで、rubyを実行。

>ruby resize.rb

そうすると、同じ階層に test_resized.jpg というリサイズされたファイルが出来上がります。もちろんgifでもおkです。



※この場合、画像比率が3:4の場合のみ成立します。比率を変えないで修正したい場合は、コチラ様→Railsで画像サイズを"簡単に"操る(Image Size in Rails) - 京の路が参考になると思われます。


※試した環境

OS : Windows XP

Ruby : 1.8.6

Rails : 1.2.3

rmagick :1.13.0

ImageMagick :6.2.9 Q8