ブログ

読んで思い出す。忘れるために書く

Markdown 書式のリストからリンクを抜き出す

RedcarpetNokogiri に全力で乗っかっていく

なぜ書くのか

「なんとなく」が答え

普段、Google Chrome 拡張の Copy as Markdown を使っている

それがあるとタブの情報(タイトル, URL)を、複数選択して一度に取ってこれる

そこからURL やタイトルを個別に持ってこられると他の用途として処理を組み込んだり利用できそうな気がした

テストを書く(RSpec)

テストを書くのと実装を書く順序は "絶対遵守" ではないので、あまり気にしない("二人三脚" のためにある)

でも今回は簡単な内容なのでテストを先に書く

describe LinkExtractor do
  context 'passing multiple link with markdown style list' do
    let(:links) do
      %w[
        * [example1](example.com)
        * [example2](example.com)
        * [example3](example.com)
      ].join("\n")
    end

    it 'convert to 3 of url' do
      link_extractor = LinkExtractor.new(links)
      expect(link_extractor.to_urls.size).to eq 3
    end

    it 'gets a url' do
      link_extractor = LinkExtractor.new(links)
      link = link_extractor.to_urls.first
      expect(link).to eq 'example.com'
    end

    it 'gets a title' do
      link_extractor = LinkExtractor.new(links)
      link = link_extractor.to_titles.first
      expect(link).to eq 'example1'
    end
  end
end

実装を書く

require 'redcarpet'
require 'nokogiri'

class LinkExtractor
  def initialize(markdown_list_links)
    # markdown_list_links expects string as below:
    # * [example1](example.com)
    # * [example2](example.com)
    # * [example3](example.com)
    html = Markdown.new(markdown_list_links).to_html
    @html = Nokogiri::HTML(html)
  end

  def to_urls
    @html.css('a').map { |element| element.attribute('href').value }
  end

  def to_titles
    @html.css('a').map(&:text)
  end
end

Links