require 'erb' require 'date' require 'htmlcompressor' require 'kramdown' require 'pathname' require 'rainbow' require 'yaml' require 'zine' require 'zine/templates' module Zine # A page on the site where the content comes from a file's markdown, and the # destination's location mirrors its own class Page attr_reader :formatted_data # the meta data, passed formatted to the template class FormattedData attr_accessor :data attr_accessor :footer_partial attr_accessor :header_partial attr_accessor :html attr_reader :page attr_accessor :uri def initialize(front_matter, site_opt) @page = { date_rfc3339: front_matter['date'], date_us: parse_date(front_matter['date']), github_name: site_opt['options']['github_name'], num_items_on_home: site_opt['options']['num_items_on_home'], site_author: site_opt['options']['site_author'], site_description: site_opt['options']['site_description'], site_name: site_opt['options']['site_name'], site_URL: site_opt['options']['site_URL'], tags: slugify_tags(front_matter['tags']), title: front_matter['title'], twitter_name: site_opt['options']['twitter_name'] } end def parse_date(_d) DateTime.rfc3339(front_matter['date']).strftime('%B %-d, %Y') rescue '' end def public_binding binding end def slugify_tags(tags) return unless tags && tags.any? tags.map { |tag| { name: tag, tag_slug: Page.slug(tag) } } end end # the Tags on a Post TagData = Struct.new(:tagsArray, :destURL, :pageTitle, :pageDate, :pageDateUS) def initialize(md_file_name, dest, templates, site_options) file_parts = File.open(md_file_name, 'r').read.split('---') @formatted_data = FormattedData.new(parse_yaml(file_parts[1]), site_options) @dest_path = dest @raw_text = file_parts[2] init_templates(templates) end def init_templates(templates) @header_partial = templates.header @footer_partial = templates.footer @template = templates.body end def parse_markdown @formatted_data.html = Kramdown::Document.new( @raw_text, input: 'GFM', auto_ids: false, smart_quotes: %w(apos apos quot quot), syntax_highlighter: 'rouge' ).to_html end def parse_yaml(text) YAML.safe_load text rescue Psych::Exception puts Rainbow("Could not parse front matter for: #{md_file_name}").red { 'date' => DateTime.now.to_s, 'title' => md_file_name, 'tags' => [] } end def rel_path_from_build_dir(path) full = Pathname(path) full.relative_path_from(Pathname(@build_dir)) end def process parse_markdown html = template_the_html compressor = HtmlCompressor::Compressor.new File.write(@dest_path, compressor.compress(html)) end def self.slug(text) text.downcase .gsub(/[^a-z0-9]+/, '-') .gsub(/^-|-$/, '') end def template_the_html @formatted_data.header_partial = @header_partial.result(@formatted_data .public_binding) @formatted_data.footer_partial = @footer_partial.result(@formatted_data .public_binding) @template.result(@formatted_data.public_binding) end end end