• 追加された行はこの色です。
  • 削除された行はこの色です。
[[ネタ記録庫/Scala/dispatch]]

*文字列に含まれるURLをリンクタグにしたり、@で始まる文字列をTwitterアカウントへのリンクタグにしたりしてNodeSeqで返す [#a1b4237e]

pomu0325さんのブログ記事のコードを拡張してみた。
- 元ネタ: [[文字列に含まれるURLをaタグにしてNodeSeqで返す - pomu0325:http://pomu0325.blogspot.com/2010/03/scala-urlanodeseq.html]]

格調で追加したのは次の二つ
- @で始まる文字列をtwitterアカウントへのリンクタグに変換
- #で始まる文字列をtwitterのハッシュタグに変換
効率は知らない。


  def linkURL(s: String): NodeSeq = {
    import util.matching._
    class FirstMatch(pattern: Regex) {
      def c2s(c: CharSequence): String = c.toString  
      def unapply(s: String) =
        pattern.findFirstMatchIn(s) map {
	  case m => (c2s(m.before), m.matched, c2s(m.after))
        }
    }
    val link = new FirstMatch("""http://[\d\w\-\./%?=#]+""".r)
    val reply = new FirstMatch("""@[a-zA-Z0-9]+""".r)
    val hashtag = new FirstMatch("""#[a-zA-Z0-9]+""".r)
    s match {
      case link(before, s, after) =>
        linkURL(before) ++ <a href={s}>{xml.Text(s)}</a> ++ linkURL(after)
      case reply(before, s, after) =>
        val href = "http://twitter.com/"+s.drop(1)
        linkURL(before) ++ <a href={href}>{xml.Text(s)}</a> ++ linkURL(after)
      case hashtag(before, s, after) =>
        val href = "/?q="+Helpers.urlEncode(s)
        linkURL(before) ++ <a href={href}>{xml.Text(s)}</a> ++ linkURL(after)
      case s => xml.Text(s)
    }
  }

これはさらに次のように拡張できる。次の例はTwitterのAPIが返す文字列がhtmlエンコードされているのを安全に戻している。
  def linkURL(s: String): NodeSeq = {
    import util.matching._
    class FirstMatch(pattern: Regex) {
      def c2s(c: CharSequence): String = c.toString  
      def unapply(s: String) =
        pattern.findFirstMatchIn(s) map {
	  case m => (c2s(m.before), m.matched, c2s(m.after))
        }
    }
    val link = new FirstMatch("""http://[\d\w\-\./%?=#]+""".r)
    val reply = new FirstMatch("""@[a-zA-Z0-9]+""".r)
    val hashtag = new FirstMatch("""#[a-zA-Z0-9]+""".r)
    val amp = new FirstMatch("&amp;".r)
    val lt = new FirstMatch("&lt;".r)
    val gt = new FirstMatch("&gt;".r)
    val quote = new FirstMatch("&quot;".r)
    s match {
      case link(before, s, after) =>
        linkURL(before) ++ <a href={s}>{xml.Text(s)}</a> ++ linkURL(after)
      case reply(before, s, after) =>
        val href = "http://twitter.com/"+s.drop(1)
        linkURL(before) ++ <a href={href}>{xml.Text(s)}</a> ++ linkURL(after)
      case hashtag(before, s, after) =>
        val href = "/?q="+Helpers.urlEncode(s)
        linkURL(before) ++ <a href={href}>{xml.Text(s)}</a> ++ linkURL(after)
      case lt(before,_,after) =>
        linkURL(before) ++ xml.Text("<") ++ linkURL(after)
      case gt(before,_,after) =>
        linkURL(before) ++ xml.Text(">") ++ linkURL(after)
      case quote(before,_,after) =>
        linkURL(before) ++ xml.Text("\"") ++ linkURL(after)
      case amp(before,_,after) =>
        linkURL(before) ++ xml.Text("&") ++ linkURL(after)
      case s => xml.Text(s)
    }
  }


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS