Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
executable file 210 lines (159 sloc) 5.31 KB
#!/usr/local/bin/ruby
require 'erb'
require 'yaml'
require 'front_matter_parser'
require 'colorize'
require 'fileutils'
require 'open-uri'
# + art
# + single-file static blog generator
#
# + Author : Halis Duraki <duraki@linuxmail.org>
# + Website: https://duraki.github.io
class Art
# => Config mockup
CONFIG_MOCKUP = "https://gist.githubusercontent.com/duraki/9549f72f90a3c73a777efcdcea595576/raw/e36faa42a7a62afe10d7878aa1d63eba6e936b34/art.yaml"
WWW_DIR = ""
def init(name)
Dir.mkdir "./#{name}"
Dir.mkdir "./#{name}/#{WWW_DIR}"
Dir.mkdir "./#{name}/#{WWW_DIR}/posts/i"
Dir.mkdir "./#{name}/#{WWW_DIR}/posts/o"
mockup = open(CONFIG_MOCKUP)
puts "Generating mockup for blog: #{name} ..."
IO.copy_stream(mockup, "./#{name}/.home.yml")
puts "Done!".blue + " Edit your `.home.yml` file in ./#{name}/, and start writing :)"
end
def cli
if ARGV[0] == "init" && !ARGV[1].nil?
init(ARGV[1])
end
if ARGV[0] == "publish"
builder
end
exit
end
# Init.
def initialize
puts "art".blue + " is a standalone, single-file static blog generator.".green
puts "---------".red
puts "init <blog>".blue + " | Start a new blog, initialize directory"
puts "publish".blue + " | Publish blog from this directory"
cli
end
# Build.
def builder
puts "[+] Loading `.home.yml` from this directory ...".green
@home = YAML.load_file('.home.yml')
puts "[+] File loaded.".green
puts "---------".red
puts "[+] Creating build configuration ...".green
builder = Build.new @home
end
end
class Build
attr_accessor :artist, :title, :description
attr_accessor :posts_in, :posts_out
attr_accessor :script_list, :theme, :ga
attr_accessor :post_title, :post_date
def initialize config
self.theme = config['minimal']['theme']
puts "[+] Detecting theme ... ".red + self.theme
overwrite_theme self.theme # rebuild theme assets
puts "[+] Reading `#{self.theme}/index.erb` file ...".green
@template = File.read("./#{self.theme}/index.erb")
puts "[+] Index layout loaded.".green
puts "[+] Creating accessors from YAML file ...".green
puts "---------".red
self.artist = config['minimal']['artist']
puts "[+] Detecting who you are ... ".red + self.artist
self.title = config['minimal']['title']
puts "[+] Detecting blog title ... ".red + self.title
self.description = config['minimal']['description']
puts "[+] Detecting blog description ...".red + " [detected] "
self.posts_in = config['posts']['in']
puts "[+] Detecting input directory ... ".red + "#{Art::WWW_DIR}" + self.posts_in
self.posts_out = config['posts']['out']
puts "[+] Detecting output directory ...".red + "#{Art::WWW_DIR}" + self.posts_out
self.script_list = config['scripts']
puts "[+] Building script list ... ".red + " [built] "
self.ga = config['art']['ga']
puts "[+] Detecting Google Analytics ...".red + "[#{self.ga}]"
puts "[x] Accessors built.".green
puts "---------".red
puts "[+] Exporting markdown to HTML ...".green
exec = self.cli # generate html from mdc
system(exec + "> /dev/null") # exec generation process
puts "[+] Building metadata & posts ...".green
list = posts # get all .md files
beauty(list) # build by metadata
puts "[+] Building scripts ...".green
scripts(self.script_list)
puts "[+] All systems ready ...".green
puts "---------".red
write
end
# Generate html from markdown using `markdown-html` node module
def cli
return "generate-md --layout ./#{self.theme} --input .#{Art::WWW_DIR}#{self.posts_in} --output .#{Art::WWW_DIR}#{self.posts_out}"
end
# Generate scripts and appropriate locations
def scripts list
@scriptarr = {}
list.each_with_index do |item, index|
@scriptarr[index] = {name: item.split(':')[1], title: item.split(':')[0]}
end
@scriptarr
end
# Get posts by id-s
def posts
list = Array.new
Dir["."+Art::WWW_DIR+self.posts_in+"/*.md"].each do |f|
list.push(f)
end
list.sort_by! {|s| s[/\d+/].to_i}
list
end
# Helper method to beauty post list
def beauty list
hashed = {}
i = 0
list.each do |file|
extract_metadata(file)
i=i+1
hashed[i] = { id: extract_id(file), filename: file, title: @post_title, date: @post_date, out: @post_out}
end
@all_posts = Hash[hashed.to_a.reverse]
end
# Extract ID of post
def extract_id file
file.match(/[0-9]{4}/).to_a[0]
id = file.match(/[0-9]{4}/).to_a[0]
id.to_s
end
# Extract metadata / frontmatter from yaml post
def extract_metadata file
metadata = FrontMatterParser::Parser.parse_file(file)
metadata.front_matter
@post_title = metadata.front_matter['title']
@post_date = metadata.front_matter['date']
@post_out = file.sub '.md', '.html'
@post_out = @post_out.sub self.posts_in, self.posts_out
end
# Write results with erb
def write
puts "[+] Binding results ...".green
erb = ERB.new(@template)
File.open(".#{Art::WWW_DIR}/index.html", 'w') do |f|
f.write erb.result(binding)
end
puts "[x] All done.".green
end
# Overwrite assets / theme
def overwrite_theme theme
FileUtils.cp_r Dir["#{theme}/assets/*"], ".#{Art::WWW_DIR}/assets/"
end
end
# Initialize.
art = Art.new
#art.builder