Class: TxtBook

Inherits:
Object show all
Includes:
HeaderDetect
Defined in:
lib/txt_book.rb

Overview

文本书籍

处理TXT格式的书籍。

 1. 文档的编码格式必须是UTF-8或GB2312,推荐使用UTF-8格式
 2. 文档的内容只包含书内容部分(书名、作者、目录等信息应该不包含在文档内)
 3. 文档的段落应该完整(有些PDF转换过来的文档会破坏句子,需要进行预处理)
 4. 文档必须符合正常的文档流(错位的章节段落等情况将影响正常的结构提取)
 5. 文档需要包含结构信息(例如: 卷、篇、部分、章(回)节或者有连续的序号)
 6. 每个结构信息都应该独立成行。

文本书籍现状

目前来说,文本书籍的目录结构情况并非如想像的完整,主要存在以下几方面问题:
 1. 目录结构问题
    文本文件中包含的目录情况主要有以下几种:
       * 不包含目录结构。 典型的如诗歌、散文类电子书
       * 包含目录结构,同时列出目录。 典型的如在文件开头部分列出了电子书的目录
       * 目录结构信息是以节、讲、则组成的。
       * 目录信息被特殊的信息包裹。例如: "第一节: 第一章xxxxxxx",">>>>"等
       * 目录信息本身就有误。有些书本身就是不完整的书,目录信息不完整。
       * 信息层级结构错位,没有按照卷(篇)、章(回)、节的顺序来组织,或因为部分信息被不正确的关联到其他内容后面,导致无法识别。

 2. 内容问题
     内容问题主要来自两个问题:
       * 页眉、页脚问题。很多从PDF转换过来的书都包含了页眉页脚
       * 断句问题。 很多PDF转换过来的电子书都有断句问题。

解决办法

问题1: 不包含目录结构

这类书籍没有办法进行处理

问题2: 包含目录结构,同时列出目录

这类书籍先要检测列出的目录并将该内容从文件内容中剥离,防止重复提取。
有些列出的目录并不是完全符合目录结构信息,在这里只能进行猜测。猜测规则:
  1. 假设列出的目录总行数不会超过50行
  2. 只要在50行内连续出现60%以上章节的信息即作为目录块

问题3: 目录结构信息是以节等组成

将节、讲、则作为标题的构成部分

Constant Summary

Constants included from HeaderDetect

HeaderDetect::HEAD_TYPES

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from HeaderDetect

#guess_appendix?, #guess_chapter?, #guess_digital_header?, #guess_digital_section?, #guess_glossary?, #guess_header?, #guess_index?, #guess_part?, #guess_preface?, #guess_section?, #guess_volume?, #hav_complete_sentence?, #valid_title?

Constructor Details

#initialize(content, options = {}) ⇒ TxtBook

Returns a new instance of TxtBook.



56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/txt_book.rb', line 56

def initialize(content,options={})
  @title = options[:title]
  @author = options[:author]
  @publisher = options[:publisher]
  @pubdate= options[:pubdate]
  @isbn = options[:isbn]
  @format = options[:format]

  unless Utils.detect_utf8(content)
    content = Utils.to_utf8(content) 
  end

  @content = preprocess_content(content)
end

Instance Attribute Details

#authorObject (readonly)

Returns the value of attribute author.



47
48
49
# File 'lib/txt_book.rb', line 47

def author
  @author
end

#contentObject (readonly)

Returns the value of attribute content.



47
48
49
# File 'lib/txt_book.rb', line 47

def content
  @content
end

#isbnObject (readonly)

Returns the value of attribute isbn.



47
48
49
# File 'lib/txt_book.rb', line 47

def isbn
  @isbn
end

#pubdateObject (readonly)

Returns the value of attribute pubdate.



47
48
49
# File 'lib/txt_book.rb', line 47

def pubdate
  @pubdate
end

#publisherObject (readonly)

Returns the value of attribute publisher.



47
48
49
# File 'lib/txt_book.rb', line 47

def publisher
  @publisher
end

#titleObject (readonly)

Returns the value of attribute title.



47
48
49
# File 'lib/txt_book.rb', line 47

def title
  @title
end

Class Method Details

.load(filename, options = {}) ⇒ Object



49
50
51
52
53
54
# File 'lib/txt_book.rb', line 49

def self.load(filename,options={})
  raise '无效的文件' unless File.exists?(filename)
  options[:title] = File.basename(filename, File.extname(filename))
  content = File.open(filename).read
  new(content,options)
end

Instance Method Details

#breaklinesObject



81
82
83
# File 'lib/txt_book.rb', line 81

def breaklines
  @breaklines ||= Utils.breaklines(content)
end

#breaklines_countObject



85
86
87
# File 'lib/txt_book.rb', line 85

def breaklines_count
  breaklines.count
end

#struct_contentObject



71
72
73
74
75
76
77
78
79
# File 'lib/txt_book.rb', line 71

def struct_content
  return @struct_content if @struct_content 
  content = if breaklines_count > 100
              Utils.fixed_page_break(@content)
            else
              @content
            end
  @struct_content = extract_book_struct(content,:format=>@format)
end

#to_doc_bookObject



101
102
103
104
105
106
107
# File 'lib/txt_book.rb', line 101

def to_doc_book
  if struct_content
    build_doc_book(struct_content,{:title=>title,:publisher=>publisher,:pubdate=>pubdate,:author=>author,:isbn=>isbn})    
  else
    build_doc_book(content,{:title=>title,:publisher=>publisher,:pubdate=>pubdate,:author=>author,:isbn=>isbn})
  end
end

#tocObject



89
90
91
# File 'lib/txt_book.rb', line 89

def toc
  @toc ||= extract_toc_from_struct(struct_content) if struct_content
end

#toc_to_textObject



93
94
95
96
97
98
99
# File 'lib/txt_book.rb', line 93

def toc_to_text
  if toc
    gen_toc(toc) do |item,children|
      "#{item[:title]}\n#{children}"
    end
  end
end