# Marks TextBlocks which contain parts of the HTML tag, using # some heuristics which are quite specific to the news domain. # we create a list of potential titles from the page title # then we look at every text block and if the text block # contains a potential title - we set that text block label as :TITLE module Boilerpipe::Filters class DocumentTitleMatchClassifier attr_reader :potential_titles def initialize(title) @potential_titles = Set.new generate_potential_titles(title) end def process(doc) return doc if @potential_titles.empty? doc.text_blocks.each do |tb| text = tb.text.gsub('\u00a0', ' ') .gsub("'", '') .strip.downcase if @potential_titles.member? text tb.add_label :TITLE break end remove_characters = /[?!.-:]+/ text = text.gsub(remove_characters, '').strip if @potential_titles.member? text tb.add_label :TITLE break end end doc end private def generate_potential_titles(title) return if title.nil? title = title.gsub('\u00a0', ' ') .gsub("'", '') .strip .downcase @potential_titles << title # unnecessary # p = longest_part(title, /[ ]*[|»-][ ]*/) # @potential_titles << p if p # p = longest_part(title, /[ ]*[|»:][ ]*/) # @potential_titles << p if p # p = longest_part(title, /[ ]*[|»:()][ ]*/) # @potential_titles << p if p # p = longest_part(title, /[ ]*[|»:()-][ ]*/) # @potential_titles << p if p p = longest_part(title, /[ ]*[|»,:()-][ ]*/) @potential_titles << p if p # we replace \u00a0 so why check for it? # p = longest_part(title, /[ ]*[|»,:()-\u00a0][ ]*/) # @potential_titles << p if p add_potential_titles(title, /[ ]+[|][ ]+/, 4) add_potential_titles(title, /[ ]+[-][ ]+/, 4) @potential_titles << title.sub(/ - [^-]+$/, '') # remove right of - @potential_titles << title.sub(/^[^-]+ - /, '') # remove left of - end def longest_part(title, regex) parts = title.split regex return nil if parts.size == 1 longest_num_words = 0 longest_part = '' parts.each do |part| next if part =~ /[.]com/ num_words = number_of_words(part) if num_words > longest_num_words || part.size > longest_part.size longest_num_words = num_words longest_part = part end end longest_part.empty? ? nil : longest_part.strip end def add_potential_titles(title, regex, min_words) parts = title.split regex return if parts.size == 1 parts.each do |part| next if part =~ /[.]com/ num_words = number_of_words(part) @potential_titles << part if num_words >= min_words end end def number_of_words(s) s.split(/[\b ]+/).size end end end