class BlogGenerator::Post
Constants
- REGEXP
Attributes
format[R]
metadata[R]
site[R]
Public Class Methods
new(site, path)
click to toggle source
# 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.load_metadata @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
Public Instance Methods
absolute_url()
click to toggle source
# File lib/blog-generator/post.rb, line 65 def absolute_url [site.base_url, self.relative_url].join('') end
as_json()
click to toggle source
# File lib/blog-generator/post.rb, line 130 def as_json @metadata.merge(body: self.post_processed_body).tap do |metadata| metadata[:published_at] && metadata[:published_at] = DateTime.parse(metadata[:published_at]) metadata[:updated_at] && metadata[:updated_at] = DateTime.parse(metadata[:updated_at]) end end
body()
click to toggle source
# File lib/blog-generator/post.rb, line 73 def body @body ||= begin process_body(nokogiri_raw_document.dup) end end
email()
click to toggle source
# File lib/blog-generator/post.rb, line 53 def email self.metadata[:email] || site.email end
excerpt()
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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
links()
click to toggle source
# 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_metadata()
click to toggle source
# File lib/blog-generator/post.rb, line 43 def load_metadata self.raw_metadata.reduce(Hash.new) do |buffer, (slug, value)| buffer.merge(slug.to_sym => try_to_dup(value)) end end
post_process_body(text)
click to toggle source
This is a terrible hack to make unescaped code possible.
# 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_body()
click to toggle source
# 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)
click to toggle source
# 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_body()
click to toggle source
# File lib/blog-generator/post.rb, line 69 def raw_body File.read(@path).match(/\n---\n(.+)$/m)[1].strip end
raw_metadata()
click to toggle source
# File lib/blog-generator/post.rb, line 37 def raw_metadata @raw_metadata ||= begin YAML.load_file(@path) || raise("Metadata in #{@path} are not valid YAML.") end end
relative_url()
click to toggle source
# File lib/blog-generator/post.rb, line 61 def relative_url "/posts/#{slug}" end
save(extra_metadata = Hash.new)
click to toggle source
# File lib/blog-generator/post.rb, line 141 def save(extra_metadata = Hash.new) extra_metadata = extra_metadata.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>} metadata = self.raw_metadata.merge(extra_metadata) <<-EOF #{metadata.map { |key, value| "#{key}: #{value}"}.join("\n")} --- #{excerpt} #{self.post_processed_body} EOF end
to_json(*args)
click to toggle source
# File lib/blog-generator/post.rb, line 137 def to_json(*args) self.as_json.to_json(*args) end
Private Instance Methods
nokogiri_raw_document()
click to toggle source
# File lib/blog-generator/post.rb, line 165 def nokogiri_raw_document @nokogiri_raw_document ||= Nokogiri::HTML(self.raw_body) end
parse_path(path)
click to toggle source
# File lib/blog-generator/post.rb, line 169 def parse_path(path) match = File.basename(path).match(REGEXP) published_on = match[1] ? Date.parse(match[1]).to_time.utc : nil [published_on, match[3], match[4].to_sym] end
try_to_dup(value)
click to toggle source
true and some others cannot be cloned.
# File lib/blog-generator/post.rb, line 176 def try_to_dup(value) value.dup rescue TypeError value end