Class: BlogGenerator::Post

Inherits:
Object
  • Object
show all
Defined in:
lib/blog-generator/post.rb

Constant Summary collapse

REGEXP =
/^((\d{4}-\d{2}-\d{2})-)?(.+)\.(html|md)$/

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(site, path) ⇒ Post

Returns a new instance of Post.



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/blog-generator/post.rb', line 18

def initialize(site, path)
  # TODO: metadata so we can construct url (base_url + relative) AND merge author
  @site, @path = site, File.expand_path(path)

  # TODO: Bring back .md from adapters/markdown.rb
  published_on, slug, format = parse_path(path)

  @metadata = self.
  @metadata.merge!(slug: slug)
  @metadata.merge!(excerpt: excerpt)
  @metadata.merge!(path: "/posts/#{slug}") ### TODO: some routing config.
  @metadata.merge!(links: self.links)

  @metadata[:tags].map! do |tag|
    slug = generate_slug(tag)
    {title: tag, slug: slug, path: "/tags/#{slug}"}
  end
end

Instance Attribute Details

#formatObject (readonly)

Returns the value of attribute format.



17
18
19
# File 'lib/blog-generator/post.rb', line 17

def format
  @format
end

#metadataObject (readonly)

Returns the value of attribute metadata.



17
18
19
# File 'lib/blog-generator/post.rb', line 17

def 
  @metadata
end

#siteObject (readonly)

Returns the value of attribute site.



17
18
19
# File 'lib/blog-generator/post.rb', line 17

def site
  @site
end

Instance Method Details

#absolute_urlObject



65
66
67
# File 'lib/blog-generator/post.rb', line 65

def absolute_url
  [site.base_url, self.relative_url].join('')
end

#as_jsonObject



130
131
132
133
134
135
# File 'lib/blog-generator/post.rb', line 130

def as_json
  @metadata.merge(body: self.post_processed_body).tap do ||
    [:published_at] && [:published_at] = DateTime.parse([:published_at])
    [:updated_at]   && [:updated_at]   = DateTime.parse([:updated_at])
  end
end

#authorObject



49
50
51
# File 'lib/blog-generator/post.rb', line 49

def author
  self.[:author] || site.author
end

#bodyObject



73
74
75
76
77
# File 'lib/blog-generator/post.rb', line 73

def body
  @body ||= begin
    process_body(nokogiri_raw_document.dup)
  end
end

#emailObject



53
54
55
# File 'lib/blog-generator/post.rb', line 53

def email
  self.[:email] || site.email
end

#excerptObject



123
124
125
126
127
128
# File 'lib/blog-generator/post.rb', line 123

def excerpt
  @excerpt ||= begin
    document = nokogiri_raw_document.dup
    document.css('#excerpt').inner_html.sub(/^\s*(.*)\s*$/, '\1').chomp
  end
end

#generate_slug(name) ⇒ Object

for tags, should go to utils or something.



57
58
59
# File 'lib/blog-generator/post.rb', line 57

def generate_slug(name) # for tags, should go to utils or something.
  name.downcase.tr(' /', '-').delete('!?')
end

#image_binary_data(asset_path) ⇒ Object



113
114
115
116
117
118
119
120
121
# File 'lib/blog-generator/post.rb', line 113

def image_binary_data(asset_path)
  require 'base64'

  extension    = File.extname(asset_path)[1..-1]
  binary_data  = File.read(asset_path)
  encoded_data = Base64.encode64(binary_data)

  "data:image/#{extension};base64,#{encoded_data}"
end


158
159
160
161
162
# File 'lib/blog-generator/post.rb', line 158

def links
  nokogiri_raw_document.css('a[href^="/posts/"]').map do |anchor|
    anchor.attribute('href').value
  end.uniq
end

#load_metadataObject



43
44
45
46
47
# File 'lib/blog-generator/post.rb', line 43

def 
  self..reduce(Hash.new) do |buffer, (slug, value)|
    buffer.merge(slug.to_sym => try_to_dup(value))
  end
end

#post_process_body(text) ⇒ Object

This is a terrible hack to make unescaped code possible.



99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/blog-generator/post.rb', line 99

def post_process_body(text)
  regexp = /<code lang="(\w+)"(?: file="([^"]+)")?>\n?(.*?)<\/code>/m
  p original_body_matches = self.raw_body.scan(regexp)

  text.gsub(regexp).with_index do |pre, index|
    language, file, code = original_body_matches[index]
    if file
      "<figure><figcaption class='filepath'>#{file}</figcaption><pre><code class=\"#{language}\">#{CGI.escapeHTML(code)}</code></pre></figure>"
    else
      "<pre><code class=\"#{language}\">#{CGI.escapeHTML(code)}</code></pre>"
    end
  end
end

#post_processed_bodyObject



94
95
96
# File 'lib/blog-generator/post.rb', line 94

def post_processed_body
  @post_processed_body ||= post_process_body(self.body.to_s)
end

#process_body(document) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/blog-generator/post.rb', line 79

def process_body(document)
  document.css('#excerpt').remove
  document.css('img[src^="/assets/"]').each do |img|
    absolute_url = img.attribute('src').value
    asset_path   = "..#{absolute_url}" # This is extremely shakey, it depends on us being in api.botanicus.me.
    if File.exists?(asset_path)
      img['src'] = image_binary_data(asset_path)
    else
      raise "Asset #{asset_path} doesn't exist."
    end
  end

  document.css('body').inner_html.strip
end

#raw_bodyObject



69
70
71
# File 'lib/blog-generator/post.rb', line 69

def raw_body
  File.read(@path).match(/\n---\n(.+)$/m)[1].strip
end

#raw_metadataObject



37
38
39
40
41
# File 'lib/blog-generator/post.rb', line 37

def 
  @raw_metadata ||= begin
    YAML.load_file(@path) || raise("Metadata in #{@path} are not valid YAML.")
  end
end

#relative_urlObject



61
62
63
# File 'lib/blog-generator/post.rb', line 61

def relative_url
  "/posts/#{slug}"
end

#save(extra_metadata = Hash.new) ⇒ Object



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/blog-generator/post.rb', line 141

def save( = Hash.new)
   = .reduce(Hash.new) do |buffer, (key, value)|
    buffer.merge(key.to_s => value)
  end

  excerpt = self.excerpt.empty? ? %Q{<p id="excerpt">\n</p>} : %Q{<p id="excerpt">\n  #{self.excerpt}\n</p>}
   = self..merge()
  <<-EOF
#{.map { |key, value| "#{key}: #{value}"}.join("\n")}
---

#{excerpt}

#{self.post_processed_body}
  EOF
end

#to_json(*args) ⇒ Object



137
138
139
# File 'lib/blog-generator/post.rb', line 137

def to_json(*args)
  self.as_json.to_json(*args)
end