Class: Jekyll::Site

Inherits:
Object
  • Object
show all
Defined in:
lib/jekyll/calibre.rb

Instance Method Summary collapse

Instance Method Details

#readObject

The goal here is to create books into posts without having to write them as actual files.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/jekyll/calibre.rb', line 10

def read
  # Read other posts normally
  read_one

  # Get the calibre dir from _config.yml
  calibre_dir = config.dig('calibre','dir')
  # Where to copy the covers
  cover_dir   = config.dig('calibre', 'cover', 'dir') || 'covers'

  # TODO fail if calibre_dir is missing

  # Open the database
  Calibre.db = File.join(calibre_dir, 'metadata.db')

  # For every book
  # TODO make the query customizable
  Calibre::Book.all.each do |book|
    # Create a new document on the posts collection
    # TODO use a _books collection
    post = Jekyll::Document.new('unneeded', { site: self, collection: posts })

    # The layout comes from the config
    post.data['layout'] = config.dig('calibre', 'layout') || 'post'
    # It's a markdown file
    post.data['ext'] = 'markdown'
    # The slug is the slugified title
    post.data['slug'] = Utils.slugify(book.title)
    # The title is the title :P
    post.data['title'] = book.title
    # Other metadata
    post.data['date']      = book.timestamp
    post.data['pubdate']   = book.pubdate
    post.data['author']    = book.authors.map(&:name).compact
    post.data['publisher'] = book.publishers.map(&:name).compact
    # The content comes in html but we don't care much because
    # markdown supports html
    # TODO convert to markdown anyway in case the parser gives
    # custom attributes and classes, like id's to h* tags
    post.content = book.comments.map(&:text).compact.join

    # The formats and files for easy access
    # TODO fail if missing
    files_dest = config.dig('calibre', 'files', 'dir') || 'files'
    post.data['files'] = Hash[book.data.map do |f|
      # Copy the actual files
      file      = File.join(files_dest, f.path)
      file_dest = File.join(dest, file)
      file_orig = File.join(calibre_dir, f.path)
      FileUtils.mkdir_p(File.dirname(file_dest))
      FileUtils.cp(file_orig, file_dest)
      self.keep_files << file

      # Also create a Hash { format: path } as absolute url
      [ f.format, config.fetch('baseurl', '') + '/' + file ]
    end]

    # Copy the covers to the final site
    if book.cover?
      # Where in the metadata we want to store the path to cover
      cover_field = config.dig('calibre', 'cover', 'field') || 'cover'
      # The path is the absolute URL
      post.data[cover_field] = "#{config.fetch('baseurl', '')}/#{cover_dir}/#{book.cover}"

      # The cover is stored in a path mimicking the path from
      # calibre
      # TODO maybe use the slug or something, calibre uses spaces in
      # directories :(
      post_dir   = File.join(dest, cover_dir, book.path)
      # Original cover
      cover      = File.join(calibre_dir, book.cover)
      # Final cover
      dest_cover = File.join(post_dir, 'cover.jpg')

      # Create the directory and copy the file
      FileUtils.mkdir_p(post_dir)
      FileUtils.cp(cover, dest_cover)

      # Tell Jekyll to keep the files once finishes building
      # keep_files needs the relative path
      self.keep_files << File.join(cover_dir, book.cover)
    end

    # Add the book to the _posts collection
    posts.docs << post
  end
end

#read_oneObject



6
# File 'lib/jekyll/calibre.rb', line 6

alias_method :read_one, :read